├── src
├── varion_frontend
│ ├── src
│ │ ├── vite-env.d.ts
│ │ ├── assets
│ │ │ └── ICLogoWhite.png
│ │ ├── main.jsx
│ │ ├── index.scss
│ │ ├── App.jsx
│ │ ├── landing
│ │ │ ├── roadmap.jsx
│ │ │ └── homepage.jsx
│ │ └── dashboard
│ │ │ ├── patients.jsx
│ │ │ └── dashboard.jsx
│ ├── public
│ │ ├── favicon.ico
│ │ ├── TechArch.png
│ │ ├── gradientBg.jpg
│ │ ├── varionlogo.png
│ │ └── varionlogoOnly.png
│ ├── index.html
│ ├── tsconfig.json
│ ├── package.json
│ └── vite.config.js
└── varion_backend
│ ├── src
│ ├── model.onnx
│ └── lib.rs
│ ├── varion_backend.did
│ └── Cargo.toml
├── assets
└── banner.jpg
├── Cargo.toml
├── tsconfig.json
├── .gitignore
├── dfx.json
├── package.json
├── README.md
└── Cargo.lock
/src/varion_frontend/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/assets/banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/assets/banner.jpg
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = [
3 | "src/varion_backend"
4 | ]
5 | resolver = "2"
6 |
--------------------------------------------------------------------------------
/src/varion_backend/src/model.onnx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_backend/src/model.onnx
--------------------------------------------------------------------------------
/src/varion_frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/public/favicon.ico
--------------------------------------------------------------------------------
/src/varion_frontend/public/TechArch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/public/TechArch.png
--------------------------------------------------------------------------------
/src/varion_frontend/public/gradientBg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/public/gradientBg.jpg
--------------------------------------------------------------------------------
/src/varion_frontend/public/varionlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/public/varionlogo.png
--------------------------------------------------------------------------------
/src/varion_frontend/public/varionlogoOnly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/public/varionlogoOnly.png
--------------------------------------------------------------------------------
/src/varion_frontend/src/assets/ICLogoWhite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VarionAI/varion/HEAD/src/varion_frontend/src/assets/ICLogoWhite.png
--------------------------------------------------------------------------------
/src/varion_backend/varion_backend.did:
--------------------------------------------------------------------------------
1 | type PredictionFailed = record {
2 | message : text;
3 | };
4 |
5 | type PredictionResult = variant {
6 | Success : text;
7 | Failure : PredictionFailed;
8 | };
9 |
10 | service : {
11 | prediction_result : (text) -> (PredictionResult);
12 | };
13 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "strict": true,
4 | "target": "ES2020",
5 | "experimentalDecorators": true,
6 | "strictPropertyInitialization": false,
7 | "moduleResolution": "node",
8 | "allowJs": true,
9 | "outDir": "HACK_BECAUSE_OF_ALLOW_JS"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Various IDEs and Editors
2 | .vscode/
3 | .idea/
4 | **/*~
5 |
6 | # Mac OSX temporary files
7 | .DS_Store
8 | **/.DS_Store
9 |
10 | # dfx temporary files
11 | .dfx/
12 |
13 | # generated files
14 | **/declarations/
15 |
16 | # rust
17 | target/
18 |
19 | # frontend code
20 | node_modules/
21 | dist/
22 | .svelte-kit/
23 |
24 | # environment variables
25 | .env
26 |
--------------------------------------------------------------------------------
/src/varion_frontend/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Varion AI
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/dfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "canisters": {
3 | "varion_backend": {
4 | "candid": "src/varion_backend/varion_backend.did",
5 | "package": "varion_backend",
6 | "type": "rust"
7 | },
8 | "varion_frontend": {
9 | "dependencies": [
10 | "varion_backend"
11 | ],
12 | "source": [
13 | "src/varion_frontend/dist"
14 | ],
15 | "type": "assets",
16 | "workspace": "varion_frontend"
17 | }
18 | },
19 | "defaults": {
20 | "build": {
21 | "args": "",
22 | "packtool": ""
23 | }
24 | },
25 | "output_env_file": ".env",
26 | "version": 1
27 | }
--------------------------------------------------------------------------------
/src/varion_frontend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": true,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx",
18 | "types": ["vite/client"]
19 | },
20 | "include": ["src"]
21 | }
22 |
--------------------------------------------------------------------------------
/src/varion_backend/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "varion_backend"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [lib]
9 | crate-type = ["cdylib"]
10 |
11 | [dependencies]
12 | candid = "0.10"
13 | ic-cdk = "0.15"
14 | ic-cdk-macros = "0.15.0"
15 | ic-cdk-timers = "0.7" # Feel free to remove this dependency if you don't need timers
16 | getrandom = { version = "0.2.15", features = ["custom"] }
17 | serde = "1.0.208"
18 | prost = "0.11.0"
19 | bytes = "1.5.0"
20 | tract-onnx = { git = "https://github.com/sonos/tract", rev = "2a2914ac29390cc08963301c9f3d437b52dd321a" }
--------------------------------------------------------------------------------
/src/varion_frontend/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import App from './App';
4 | import { InternetIdentity } from "@connect2ic/core/providers"
5 | import { createClient } from "@connect2ic/core"
6 | import { Connect2ICProvider } from "@connect2ic/react"
7 | import "@connect2ic/core/style.css"
8 |
9 | const client = createClient({
10 | providers: [
11 | new InternetIdentity()
12 | ],
13 | })
14 |
15 | ReactDOM.createRoot(document.getElementById('root')).render(
16 |
17 |
18 |
19 |
20 | ,
21 | );
--------------------------------------------------------------------------------
/src/varion_frontend/src/index.scss:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: sans-serif;
3 | font-size: 1.5rem;
4 | }
5 |
6 | img {
7 | max-width: 50vw;
8 | max-height: 25vw;
9 | display: block;
10 | margin: auto;
11 | }
12 |
13 | form {
14 | display: flex;
15 | justify-content: center;
16 | gap: 0.5em;
17 | flex-flow: row wrap;
18 | max-width: 40vw;
19 | margin: auto;
20 | align-items: baseline;
21 | }
22 |
23 | button[type="submit"] {
24 | padding: 5px 20px;
25 | margin: 10px auto;
26 | float: right;
27 | }
28 |
29 | #greeting {
30 | margin: 10px auto;
31 | padding: 10px 60px;
32 | border: 1px solid #222;
33 | }
34 |
35 | #greeting:empty {
36 | display: none;
37 | }
38 |
--------------------------------------------------------------------------------
/src/varion_frontend/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { BrowserRouter as Router, Route, Routes, Navigate } from 'react-router-dom';
2 | import Homepage from './landing/homepage';
3 | import Dashboard from './dashboard/dashboard';
4 | import { useConnect } from "@connect2ic/react"
5 |
6 | console.error = () => {};
7 |
8 | function App() {
9 | const { isConnected } = useConnect({
10 | onConnect: () => {},
11 | onDisconnect: () => {}
12 | })
13 |
14 | return (
15 |
16 |
17 | :
21 | }
22 | />
23 | :
27 | }
28 | />
29 |
30 |
31 | );
32 | }
33 |
34 | export default App;
--------------------------------------------------------------------------------
/src/varion_frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "varion_frontend",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "setup": "npm i && dfx canister create varion_backend && dfx generate varion_backend && dfx deploy",
8 | "start": "vite --port 3000",
9 | "prebuild": "dfx generate",
10 | "build": "tsc && vite build",
11 | "format": "prettier --write \"src/**/*.{json,js,jsx,ts,tsx,css,scss}\""
12 | },
13 | "dependencies": {
14 | "react": "^18.2.0",
15 | "react-dom": "^18.2.0",
16 | "@dfinity/agent": "^1.4.0",
17 | "@dfinity/candid": "^1.4.0",
18 | "@dfinity/principal": "^1.4.0"
19 | },
20 | "devDependencies": {
21 | "@types/react": "^18.2.14",
22 | "@types/react-dom": "^18.2.6",
23 | "@vitejs/plugin-react": "^4.0.1",
24 | "dotenv": "^16.3.1",
25 | "sass": "^1.63.6",
26 | "typescript": "^5.1.3",
27 | "vite": "^4.3.9",
28 | "vite-plugin-environment": "^1.1.3"
29 | }
30 | }
--------------------------------------------------------------------------------
/src/varion_frontend/vite.config.js:
--------------------------------------------------------------------------------
1 | import { fileURLToPath, URL } from 'url';
2 | import react from '@vitejs/plugin-react';
3 | import { defineConfig } from 'vite';
4 | import environment from 'vite-plugin-environment';
5 | import dotenv from 'dotenv';
6 |
7 | dotenv.config({ path: '../../.env' });
8 |
9 | export default defineConfig({
10 | build: {
11 | emptyOutDir: true,
12 | },
13 | optimizeDeps: {
14 | esbuildOptions: {
15 | define: {
16 | global: "globalThis",
17 | },
18 | },
19 | },
20 | server: {
21 | proxy: {
22 | "/api": {
23 | target: "http://127.0.0.1:4943",
24 | changeOrigin: true,
25 | },
26 | },
27 | },
28 | plugins: [
29 | react(),
30 | environment("all", { prefix: "CANISTER_" }),
31 | environment("all", { prefix: "DFX_" }),
32 | ],
33 | resolve: {
34 | alias: [
35 | {
36 | find: "declarations",
37 | replacement: fileURLToPath(
38 | new URL("../declarations", import.meta.url)
39 | ),
40 | },
41 | ],
42 | },
43 | });
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "engines": {
3 | "node": ">=16.0.0",
4 | "npm": ">=7.0.0"
5 | },
6 | "name": "varion",
7 | "scripts": {
8 | "build": "npm run build --workspaces --if-present",
9 | "prebuild": "npm run prebuild --workspaces --if-present",
10 | "pretest": "npm run prebuild --workspaces --if-present",
11 | "start": "npm start --workspaces --if-present",
12 | "test": "npm test --workspaces --if-present"
13 | },
14 | "type": "module",
15 | "workspaces": [
16 | "src/varion_frontend"
17 | ],
18 | "dependencies": {
19 | "@connect2ic/core": "^0.2.0-beta.24",
20 | "@connect2ic/react": "^0.2.0-beta.24",
21 | "@emotion/react": "^11.13.3",
22 | "@emotion/styled": "^11.13.0",
23 | "@fullpage/react-fullpage": "^0.1.42",
24 | "@mui/icons-material": "^5.16.7",
25 | "@mui/material": "^5.16.7",
26 | "@nivo/bar": "^0.87.0",
27 | "framer-motion": "^11.3.30",
28 | "react": "^18.3.1",
29 | "react-dom": "^18.3.1",
30 | "react-icons": "^5.3.0",
31 | "react-intersection-observer": "^9.13.0",
32 | "react-router-dom": "^6.26.1",
33 | "styled-components": "^6.1.12"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/varion_backend/src/lib.rs:
--------------------------------------------------------------------------------
1 | use candid::{CandidType, Deserialize};
2 | use ic_cdk::update;
3 | use prost::Message;
4 | use tract_ndarray::Array2;
5 | use tract_onnx::prelude::*;
6 | use getrandom::register_custom_getrandom;
7 |
8 | #[derive(CandidType, Deserialize)]
9 | struct PredictionFailed {
10 | message: String,
11 | }
12 |
13 | #[derive(CandidType, Deserialize)]
14 | enum PredictionResult {
15 | Success(String),
16 | Failure(PredictionFailed),
17 | }
18 | pub fn custom_getrandom(_buf: &mut [u8]) -> Result<(), getrandom::Error> {
19 | Err(getrandom::Error::UNSUPPORTED)
20 | }
21 | register_custom_getrandom!(custom_getrandom);
22 |
23 | const MODEL: &'static [u8] = include_bytes!("model.onnx");
24 |
25 | fn parse_csv_content(csv_content: &str) -> TractResult {
26 | let mean = vec![92.56008643, 104.46793431, 96.76034648, 24.68794296, 37.15878695];
27 | let std = vec![9.06523052, 21.02784219, 1.69851249, 9.43523536, 0.66558528];
28 |
29 | let rows: Vec> = csv_content
30 | .lines()
31 | .map(|line| {
32 | line.split(',')
33 | .map(|s| s.parse::().unwrap())
34 | .collect()
35 | })
36 | .collect();
37 |
38 | let shape = (rows.len(), rows[0].len());
39 | let mut array = Array2::from_shape_vec(shape, rows.into_iter().flatten().collect())?;
40 |
41 | // Apply standard scaling
42 | for (_i, mut row) in array.outer_iter_mut().enumerate() {
43 | for (j, elem) in row.iter_mut().enumerate() {
44 | *elem = (*elem - mean[j]) / std[j];
45 | }
46 | }
47 |
48 | Ok(Tensor::from(array))
49 | }
50 |
51 | fn predict(csv_content: &str) -> TractResult {
52 | let bytes = bytes::Bytes::from_static(MODEL);
53 | let proto: tract_onnx::pb::ModelProto = tract_onnx::pb::ModelProto::decode(bytes)?;
54 | let model = tract_onnx::onnx()
55 | .model_for_proto_model(&proto)?
56 | .into_optimized()?
57 | .into_runnable()?;
58 |
59 | // Parse CSV content into a tensor
60 | let tensor = parse_csv_content(csv_content)?;
61 |
62 | // Run the model with the parsed tensor
63 | let output = model.run(tvec!(tensor.into()))?;
64 |
65 | let output_tensor = output[0].to_array_view::()?;
66 | let output_vector: Vec = output_tensor.iter().cloned().collect();
67 | let output_string = output_vector.iter()
68 | .map(|v| v.to_string())
69 | .collect::>()
70 | .join(",");
71 |
72 | println!("{}", output_string);
73 | Ok(output_string.to_string())
74 | }
75 |
76 | #[update]
77 | async fn prediction_result(csv_content: String) -> PredictionResult {
78 | if csv_content.is_empty() {
79 | PredictionResult::Failure(PredictionFailed {
80 | message: "Invalid input: CSV content is empty".to_string(),
81 | })
82 | } else {
83 | match predict(&csv_content) {
84 | Ok(predictions) => PredictionResult::Success(predictions),
85 | Err(e) => PredictionResult::Failure(PredictionFailed {
86 | message: format!("Prediction failed: {}", e),
87 | }),
88 | }
89 | }
90 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Varion AI
2 |
3 |
4 |
5 | ## Overview
6 |
7 | Varion AI is an AI research group dedicated to integrating ICP's decentralized AI into healthcare systems. Our mission is to assess the capabilities and reliability of ICP's DeAI and explore its potential to enhance the modern healthcare systems and a vision of how decentralized technologies can address these issues.
8 |
9 | Powered by the Internet Computer Protocol, Varion AI provides a secure, scalable, and decentralized infrastructure, seamlessly integrating with centralized infrastructure to bridge between Web2 and Web3 data.
10 |
11 | Deployment: https://bnm7h-gqaaa-aaaap-qht7a-cai.icp0.io/
12 |
13 | ## Features
14 |
15 | - **Cardiovascular Disease Prediction**: Utilizes DeAI to analyze patient data and predict heart-related risks by evaluating metrics such as heart rate, blood pressure, oxygen saturation, respiratory rate, and temperature. This helps identify high-risk patients for timely interventions, reducing cardiovascular morbidity and mortality rates.
16 | - **Real-Time Monitoring Dashboard**: The user-friendly dashboard enables healthcare professionals to view and analyze patient data in real-time, allowing hospitals to update the spreadsheet with new ECG data every minute. This continuous updating ensures that the dashboard is consistently refreshed with the most recent information.
17 | - **Patient Management Strategies**: This feature allows healthcare professionals to easily search, filter, and sort patient data based on various criteria. Users can search for patients by ID, filter patients by risk level, and sort patients by cardiac probability. The feature provides real-time updates and visual indicators to help identify high-risk patients at a glance.
18 | - **On-Chain Inference**: Run machine learning models on a decentralized platform, leveraging the unique capabilities of DeAI on the Internet Computer.
19 |
20 | ## Technical Architecture
21 |
22 |
23 | ## Getting Started
24 |
25 | This section guides you through the initial setup of the necessary tools and environments for this project. We are using Rust with WebAssembly and the Dfinity platform.
26 |
27 | ### Rust Setup
28 |
29 | First, ensure you have Rust installed. We will then set the default toolchain to stable and add the WebAssembly target.
30 |
31 | 1. Install Rust and Cargo (if not already installed): Visit [Rust's installation page](https://www.rust-lang.org/tools/install).
32 | 2. Set the default toolchain to stable:
33 | ```bash
34 | rustup default stable
35 | ```
36 | 3. Add the WebAssembly target:
37 | ```bash
38 | rustup target add wasm32-unknown-unknown
39 | ```
40 |
41 | ### Node Package Installation
42 | Next, ensures that the project has all the necessary libraries and tools to run or build the application.
43 | ```bash
44 | npm install
45 | ```
46 |
47 | ### Dfinity's DFX Setup
48 |
49 | We will be using Dfinity's `dfx` for our development environment.
50 |
51 | 1. Install Dfinity's `dfx`: Follow the instructions on [Dfinity's SDK documentation](https://sdk.dfinity.org/docs/quickstart/quickstart.html).
52 | 2. Starts the replica, running in the background:
53 | ```bash
54 | dfx start --background
55 | ```
56 | 3. Deploys your canisters to the replica and generates your candid interface:
57 | ```bash
58 | dfx deploy
59 | ```
60 |
61 | ### Start the Development Server
62 | If you are making frontend changes, you can start a development server.
63 | ```bash
64 | npm start
65 | ```
66 |
67 | ## Varion's User Manual
68 | Once deployment is complete, check out Varion's User Manual for a comprehensive guide on how to fully utilize the application at [Varion Gitbook](https://varion.gitbook.io/varion-ai-documentation).
69 |
70 | ## Developers
71 | - Anders Willard Leo - ML Engineer
72 | - Alden Budiman - Product Manager
73 | - Brian Altan - Project Lead
74 | - Kenneth Bryan - Web3 Engineer
75 | - Terris Alvin - UI/UX Designer
76 |
77 | ## License
78 |
79 | Apache 2.0/MIT
80 | All original work licensed under either of
81 |
82 | Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
83 | MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT) at your option.
84 |
--------------------------------------------------------------------------------
/src/varion_frontend/src/landing/roadmap.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import { Box, Typography, Grow, useMediaQuery } from '@mui/material';
3 | import { styled } from '@mui/material/styles';
4 | import { useInView } from 'react-intersection-observer';
5 | import { useTheme } from '@mui/material/styles';
6 | import FiberManualRecordIcon from '@mui/icons-material/FiberManualRecord';
7 |
8 | const RoadmapContainer = styled(Box)(({ theme }) => ({
9 | display: 'flex',
10 | flexDirection: 'column',
11 | position: 'relative',
12 | padding: '80px 20px',
13 | width: '100%',
14 | maxWidth: '1200px',
15 | margin: '0 auto',
16 | [theme.breakpoints.up('md')]: {
17 | flexDirection: 'row',
18 | justifyContent: 'space-between',
19 | alignItems: 'stretch',
20 | },
21 | }));
22 |
23 | const Milestone = styled(Box)(({ theme, position }) => ({
24 | display: 'flex',
25 | flexDirection: 'column',
26 | alignItems: 'center',
27 | width: '100%',
28 | marginBottom: '40px',
29 | zIndex: 2,
30 | transition: 'transform 0.3s ease-in-out',
31 | '&:hover': {
32 | transform: 'translateY(-5px)',
33 | },
34 | [theme.breakpoints.up('md')]: {
35 | width: '30%',
36 | position: 'absolute',
37 | left: position === 'left' ? '0%' : position === 'center' ? '35%' : '70%',
38 | marginBottom: 0,
39 | height: 'auto',
40 | display: 'flex',
41 | flexDirection: 'column',
42 | justifyContent: 'flex-start',
43 | },
44 | }));
45 |
46 | const TextBox = styled(Box)(({ theme, maxHeight }) => ({
47 | width: '100%',
48 | padding: '20px',
49 | backgroundColor: theme.palette.background.paper,
50 | borderRadius: '8px',
51 | boxShadow: '0 4px 6px rgba(0,0,0,0.1)',
52 | marginTop: '20px',
53 | [theme.breakpoints.up('md')]: {
54 | marginTop: '30px',
55 | height: maxHeight,
56 | },
57 | }));
58 |
59 | const Circle = styled(Box)(({ color, theme }) => ({
60 | width: '30px',
61 | height: '30px',
62 | borderRadius: '50%',
63 | backgroundColor: color,
64 | boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
65 | transition: 'transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out',
66 | '&:hover': {
67 | transform: 'scale(1.1)',
68 | boxShadow: '0 6px 12px rgba(0,0,0,0.2)',
69 | },
70 | [theme.breakpoints.up('md')]: {
71 | position: 'absolute',
72 | top: '-15px',
73 | },
74 | }));
75 |
76 | const roadmapData = [
77 | {
78 | quarter: "Q3 2024",
79 | color: '#0047AB',
80 | heading: [
81 | 'Implementing [Internet Identity].',
82 | 'Implementing [On-chain Deep Learning Model Inference/DeAI].',
83 | 'Providing [Data Insights] and [Graphical Reports].',
84 | 'Releasing to [Mainnet] (Minimum-Viable-Product).'
85 | ],
86 | position: 'left'
87 | },
88 | {
89 | quarter: "Q4-Q1 2025",
90 | color: '#4169E1',
91 | heading: [
92 | '[Pre-seed] Funding.',
93 | 'Implementing [Proxy Bridge] to connect [Varion Web3] to [Web2 technologies].',
94 | 'Conducting [Open Beta] to test unreleased features on [Testnet/Playground] (Iterative Development).'
95 | ],
96 | position: 'center'
97 | },
98 | {
99 | quarter: "Q2-Q3 2025",
100 | color: '#6495ED',
101 | heading: [
102 | 'Implementing [Fully On-chain Training] & [Model Inference/Pure DeAI].',
103 | '[Direct Data Transmission] from Hospital\'s [ECG] data to Varion.',
104 | 'Joining on-site blockchain events to [promote Varion] & [ICP Capabilities].',
105 | 'Releasing to [Mainnet] (Market-Fit).'
106 | ],
107 | position: 'right'
108 | },
109 | ];
110 |
111 | const MilestoneWithAnimation = ({ milestone, index, maxHeight }) => {
112 | const [ref, inView] = useInView({
113 | triggerOnce: true,
114 | threshold: 0.1,
115 | });
116 | const theme = useTheme();
117 | const isMobile = useMediaQuery(theme.breakpoints.down('md'));
118 |
119 | return (
120 |
121 |
126 |
127 |
138 | {milestone.quarter}
139 |
140 |
141 |
142 | {milestone.heading.map((item, i) => (
143 |
144 |
151 |
157 | {item.split('[').map((part, j) =>
158 | j === 0 ? part : (
159 |
160 | {part.split(']')[0]}
161 | {part.split(']')[1]}
162 |
163 | )
164 | )}
165 |
166 |
167 | ))}
168 |
169 |
170 |
171 |
172 | );
173 | };
174 |
175 | const AnimatedTimelineLine = () => {
176 | const [ref, inView] = useInView({
177 | triggerOnce: true,
178 | threshold: 0.1,
179 | });
180 | const theme = useTheme();
181 | const isMobile = useMediaQuery(theme.breakpoints.down('md'));
182 |
183 | return (
184 |
194 |
199 |
209 |
210 |
211 | );
212 | };
213 |
214 | const Roadmap = () => {
215 | const theme = useTheme();
216 | const isMobile = useMediaQuery(theme.breakpoints.down('md'));
217 | const [maxHeight, setMaxHeight] = useState('auto');
218 |
219 | useEffect(() => {
220 | if (!isMobile) {
221 | const calculateMaxHeight = () => {
222 | let maxHeight = 0;
223 | roadmapData.forEach((milestone) => {
224 | const dummyElement = document.createElement('div');
225 | dummyElement.style.visibility = 'hidden';
226 | dummyElement.style.position = 'absolute';
227 | dummyElement.style.width = '30%';
228 | dummyElement.style.padding = '20px';
229 | document.body.appendChild(dummyElement);
230 |
231 | const content = milestone.heading.map((item) => `
232 |
233 | •
234 | ${item}
235 |
236 | `).join('');
237 |
238 | dummyElement.innerHTML = content;
239 | const height = dummyElement.offsetHeight;
240 | if (height > maxHeight) maxHeight = height;
241 |
242 | document.body.removeChild(dummyElement);
243 | });
244 |
245 | return `${maxHeight-5}px`; // Add extra padding
246 | };
247 |
248 | setMaxHeight(calculateMaxHeight());
249 |
250 | // Recalculate on window resize
251 | const handleResize = () => {
252 | setMaxHeight(calculateMaxHeight());
253 | };
254 |
255 | window.addEventListener('resize', handleResize);
256 | return () => window.removeEventListener('resize', handleResize);
257 | }
258 | }, [isMobile]);
259 |
260 | return (
261 |
262 |
263 | {roadmapData.map((milestone, index) => (
264 |
270 | ))}
271 |
272 | );
273 | };
274 |
275 | export default Roadmap;
--------------------------------------------------------------------------------
/src/varion_frontend/src/dashboard/patients.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import styled from "styled-components";
3 | import { motion, AnimatePresence } from "framer-motion";
4 | import { FiSearch, FiRefreshCw } from "react-icons/fi";
5 |
6 | const Container = styled.section`
7 | max-width: 1100px;
8 | margin: 2rem auto;
9 | padding: 2rem;
10 | background: #fff;
11 | border-radius: 20px;
12 | box-shadow: 0 12px 30px rgba(0, 0, 0, 0.06);
13 | display: flex;
14 | flex-direction: column;
15 | gap: 1.5rem;
16 | user-select: none;
17 | `;
18 |
19 | const HeaderRow = styled.div`
20 | display: flex;
21 | flex-wrap: wrap;
22 | justify-content: space-between;
23 | align-items: center;
24 | gap: 1rem;
25 | `;
26 |
27 | const Title = styled.h2`
28 | font-size: 1.8rem;
29 | font-weight: 700;
30 | color: #1e293b;
31 | flex: 1 1 auto;
32 | `;
33 |
34 | const SearchWrapper = styled.div`
35 | position: relative;
36 | flex: 1 1 300px;
37 | max-width: 400px;
38 | display: flex;
39 | align-items: center;
40 | border: 2px solid #cbd5e1;
41 | border-radius: 50px;
42 | padding: 0.5rem 1rem;
43 | background: #f1f5f9;
44 | transition: border-color 0.3s;
45 | &:focus-within {
46 | border-color: #6366f1;
47 | }
48 | `;
49 |
50 | const SearchInput = styled.input`
51 | border: none;
52 | background: transparent;
53 | outline: none;
54 | padding-left: 0.75rem;
55 | font-size: 1rem;
56 | width: 100%;
57 | color: #334155;
58 | font-weight: 500;
59 |
60 | &::placeholder {
61 | color: #94a3b8;
62 | }
63 | `;
64 |
65 | const IconSearch = styled(FiSearch)`
66 | flex-shrink: 0;
67 | color: #64748b;
68 | font-size: 1.25rem;
69 | `;
70 |
71 | const ButtonRefresh = styled.button`
72 | background: #6366f1;
73 | color: white;
74 | border: none;
75 | padding: 0.55rem 1.25rem;
76 | font-weight: 600;
77 | border-radius: 40px;
78 | display: flex;
79 | align-items: center;
80 | gap: 0.5rem;
81 | cursor: pointer;
82 | transition: background-color 0.25s;
83 |
84 | &:hover {
85 | background-color: #4f46e5;
86 | }
87 |
88 | &:focus-visible {
89 | outline: 3px solid #4f46e5;
90 | outline-offset: 2px;
91 | }
92 | `;
93 |
94 | const FiltersContainer = styled.div`
95 | display: flex;
96 | flex-wrap: wrap;
97 | gap: 12px;
98 | justify-content: center;
99 | user-select: none;
100 | `;
101 |
102 | const FilterButton = styled.button`
103 | padding: 0.5rem 1.3rem;
104 | font-weight: 600;
105 | font-size: 0.9rem;
106 | border-radius: 9999px;
107 | border: 2px solid transparent;
108 | cursor: pointer;
109 | background: ${({ active }) => (active ? "#4f46e5" : "#e0e7ff")};
110 | color: ${({ active }) => (active ? "#f3f4f6" : "#4f46e5")};
111 | transition: background-color 0.3s, color 0.3s;
112 |
113 | &:hover:not(:disabled) {
114 | background-color: ${({ active }) =>
115 | active ? "#4338ca" : "#c7d2fe"};
116 | }
117 | `;
118 |
119 | const SortContainer = styled.div`
120 | display: flex;
121 | justify-content: center;
122 | align-items: center;
123 | gap: 12px;
124 | margin-top: 0.5rem;
125 | user-select: none;
126 | `;
127 |
128 | const SortCheckbox = styled.input`
129 | cursor: pointer;
130 | width: 18px;
131 | height: 18px;
132 | `;
133 |
134 | const SortLabel = styled.label`
135 | font-weight: 600;
136 | color: #4f46e5;
137 | cursor: pointer;
138 | user-select: none;
139 | `;
140 |
141 | const LastUpdate = styled.p`
142 | text-align: center;
143 | font-size: 0.9rem;
144 | color: #64748b;
145 | margin-top: 0.5rem;
146 | font-style: italic;
147 | user-select: none;
148 | `;
149 |
150 | const TableWrapper = styled.div`
151 | overflow-x: auto;
152 | border-radius: 14px;
153 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.05);
154 | `;
155 |
156 | const TableGrid = styled.div`
157 | display: grid;
158 | grid-template-columns: repeat(7, minmax(120px, 1fr));
159 | gap: 10px;
160 | min-width: 700px;
161 |
162 | @media (max-width: 640px) {
163 | grid-template-columns: repeat(4, minmax(100px, 1fr));
164 | min-width: 400px;
165 | }
166 | `;
167 |
168 | const TableHeader = styled.div`
169 | font-weight: 700;
170 | color: #64748b;
171 | background-color: #f8fafc;
172 | padding: 14px 12px;
173 | border-radius: 10px;
174 | text-align: center;
175 | user-select: none;
176 |
177 | @media (max-width: 640px) {
178 | padding: 10px 8px;
179 | }
180 | `;
181 |
182 | const TableCell = styled(motion.div)`
183 | background-color: ${({ riskColor }) => riskColor ? riskColor : "#f8fafc"};
184 | padding: 12px 10px;
185 | border-radius: 10px;
186 | text-align: center;
187 | font-weight: 500;
188 | color: #1e293b;
189 | transition: background-color 0.3s ease;
190 |
191 | &:hover {
192 | background-color: #e0e7ff;
193 | }
194 |
195 | @media (max-width: 640px) {
196 | font-size: 0.85rem;
197 | padding: 10px 6px;
198 | }
199 | `;
200 |
201 | const getRiskColor = (riskLevel) => {
202 | switch (riskLevel) {
203 | case "High Risk":
204 | return "rgba(244, 67, 54, 0.15)";
205 | case "Medium Risk":
206 | return "rgba(255, 235, 59, 0.15)";
207 | case "Low Risk":
208 | return "rgba(76, 175, 80, 0.15)";
209 | default:
210 | return "#f8fafc";
211 | }
212 | };
213 |
214 | const Patients = ({ patientData, onRefresh }) => {
215 | const [patients, setPatients] = useState([]);
216 | const [searchTerm, setSearchTerm] = useState("");
217 | const [riskFilter, setRiskFilter] = useState("All");
218 | const [sortByRiskLevel, setSortByRiskLevel] = useState(false);
219 | const [lastUpdateTime, setLastUpdateTime] = useState("Not available");
220 |
221 | useEffect(() => {
222 | setPatients(patientData);
223 | if (patientData.length > 0 && patientData[0].lastUpdated) {
224 | setLastUpdateTime(patientData[0].lastUpdated);
225 | }
226 | }, [patientData]);
227 |
228 | const filteredAndSortedPatients = patients
229 | .filter(
230 | (p) =>
231 | p.id.toLowerCase().includes(searchTerm.toLowerCase()) &&
232 | (riskFilter === "All" || p.riskLevel === riskFilter)
233 | )
234 | .sort((a, b) => {
235 | if (sortByRiskLevel) {
236 | return b.cardiacProba - a.cardiacProba;
237 | }
238 | return 0;
239 | });
240 |
241 | return (
242 |
243 |
244 | Patient Data
245 |
246 |
247 | setSearchTerm(e.target.value)}
253 | spellCheck={false}
254 | />
255 |
256 | onRefresh && onRefresh()}
259 | >
260 |
261 | Refresh
262 |
263 |
264 |
265 |
266 | {["All", "Low Risk", "Medium Risk", "High Risk"].map((level) => (
267 | setRiskFilter(level)}
271 | aria-pressed={riskFilter === level}
272 | >
273 | {level}
274 |
275 | ))}
276 |
277 |
278 |
279 | setSortByRiskLevel(e.target.checked)}
284 | />
285 |
286 | Sort by highest Cardiac Probability
287 |
288 |
289 |
290 | Last Updated: {lastUpdateTime}
291 |
292 |
293 |
294 | Patient ID
295 | HR
296 | BP
297 | SpO₂
298 | Resp
299 | Temp (°C)
300 | Risk Level
301 |
302 |
303 | {filteredAndSortedPatients.map((patient) => (
304 |
305 |
314 | {patient.id}
315 |
316 |
317 | {patient.HR}
318 |
319 |
320 | {patient.BP}
321 |
322 |
323 | {patient.SpO2}
324 |
325 |
326 | {patient.RESP}
327 |
328 |
329 | {patient.TEMP}
330 |
331 |
332 | {patient.riskLevel}
333 |
334 |
335 | ))}
336 |
337 |
338 |
339 |
340 | );
341 | };
342 |
343 | export default Patients;
344 |
--------------------------------------------------------------------------------
/src/varion_frontend/src/landing/homepage.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import ReactFullpage from '@fullpage/react-fullpage';
3 | import { motion, AnimatePresence } from 'framer-motion';
4 | import styled from 'styled-components';
5 | import { useInView } from 'react-intersection-observer';
6 | import { ConnectButton, ConnectDialog } from '@connect2ic/react';
7 | import ArrowForwardIcon from '@mui/icons-material/KeyboardArrowRight';
8 | import ICLogo from '../assets/ICLogoWhite.png';
9 | import Roadmap from './roadmap';
10 |
11 | const featuresData = [
12 | {
13 | title: 'AI-Powered Insights',
14 | description:
15 | 'Harness AI for real-time predictive analytics on patient health and hospital operations, transforming healthcare delivery.',
16 | icon: '🧠',
17 | },
18 | {
19 | title: 'Seamless Integration',
20 | description:
21 | 'Smoothly embed Varion’s decentralized solutions within existing hospital IT infrastructure without disruption.',
22 | icon: '🔗',
23 | },
24 | {
25 | title: 'Enhanced Security',
26 | description:
27 | 'Leverage Internet Identity for decentralized secure identities — no passwords required, full privacy guaranteed.',
28 | icon: '🔐',
29 | },
30 | {
31 | title: 'On-Chain Inference',
32 | description:
33 | 'Deploy deep learning directly on-chain via Internet Computer for transparent, verifiable healthcare AI insights.',
34 | icon: '🔄',
35 | },
36 | {
37 | title: 'Scalable Architecture',
38 | description:
39 | 'Designed to scale effortlessly, Varion accommodates growing hospitals and healthcare networks anywhere globally.',
40 | icon: '📈',
41 | },
42 | {
43 | title: 'AI Model Marketplace',
44 | description:
45 | 'A decentralized store for hospitals and developers to share, license, and collaborate on specialized AI models.',
46 | icon: '🛒',
47 | },
48 | ];
49 |
50 | const FeatureCard = ({ feature, index }) => {
51 | const [ref, inView] = useInView({ threshold: 0.25, triggerOnce: true });
52 |
53 | return (
54 |
67 | {feature.icon}
68 | {feature.title}
69 | {feature.description}
70 |
71 | );
72 | };
73 |
74 | const PrivacyPolicyPopup = ({ isOpen, onClose }) => (
75 |
76 | {isOpen && (
77 |
83 | e.stopPropagation()}
88 | >
89 | ×
90 | Privacy Policy
91 |
92 | Our platform is designed with your privacy in mind, ensuring that no personal data is stored on our servers. We do not collect, retain, or share any user data. When you interact with our website, all information you provide is used solely for the duration of your session.
93 |
94 |
95 |
96 | )}
97 |
98 | );
99 |
100 | const Homepage = () => {
101 | const [isPrivacyPolicyOpen, setIsPrivacyPolicyOpen] = useState(false);
102 |
103 | return (
104 |
105 |
111 |
112 |
117 |
118 |
119 |
124 |
125 |
126 |
127 | Launch Varion
128 |
129 |
130 |
131 |
132 |
133 |
134 | (
143 |
144 |
145 |
146 |
147 |
152 | Revolutionizing Healthcare with Decentralized AI
153 |
154 |
159 | Introducing a Decentralized AI Monitoring Dashboard
160 | Elevate patient care and safety to unprecedented levels.
161 |
162 |
163 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
181 | Why Varion?
182 |
183 |
184 | {featuresData.map((feature, index) => (
185 |
186 | ))}
187 |
188 |
189 |
190 |
191 |
192 |
197 | Our Roadmap
198 |
199 |
200 |
201 |
202 |
203 |
204 |
209 | © 2024 Varion. All rights reserved.
210 |
211 |
212 | setIsPrivacyPolicyOpen(true)}
218 | >
219 | Privacy Policy
220 |
221 |
222 |
223 |
224 |
225 | )}
226 | />
227 | setIsPrivacyPolicyOpen(false)}
230 | />
231 |
232 |
233 | );
234 | };
235 |
236 | /* --- STYLED COMPONENTS --- */
237 |
238 | const Container = styled(motion.div)`
239 | font-family: 'Inter', 'Poppins', 'Helvetica Neue', Arial, sans-serif;
240 | background: linear-gradient(135deg, #e3f2fd 0%, #ffffff 100%);
241 | color: #121926;
242 | min-height: 100vh;
243 | display: flex;
244 | flex-direction: column;
245 | letter-spacing: 0.015em;
246 | font-size: 1rem;
247 | font-weight: 400;
248 | `;
249 |
250 | const Navbar = styled.nav`
251 | position: fixed;
252 | top: 0;
253 | left: 0; right: 0;
254 | height: 64px;
255 | padding: 0 2.5rem;
256 | display: flex;
257 | justify-content: space-between;
258 | align-items: center;
259 | backdrop-filter: saturate(180%) blur(12px);
260 | background: rgba(255 255 255 / 0.25);
261 | border-bottom: 1.3px solid rgba(255 255 255 / 0.4);
262 | box-shadow: 0 6px 32px rgba(20, 40, 90, 0.15);
263 | z-index: 1100;
264 |
265 | @media (max-width: 600px) {
266 | padding: 0 1.15rem;
267 | height: 54px;
268 | }
269 | `;
270 |
271 | const Logo = styled.img`
272 | height: 2.3rem;
273 | width: auto;
274 | cursor: pointer;
275 | `;
276 |
277 | const StyledConnectButton = styled.div`
278 | .connect-button {
279 | background: linear-gradient(90deg, #1a75ed 0%, #36aade 100%);
280 | color: #fff;
281 | border: none;
282 | padding: 0.55rem 1.55rem;
283 | border-radius: 23px;
284 | cursor: pointer;
285 | font-weight: 600;
286 | text-transform: uppercase;
287 | letter-spacing: 0.55px;
288 | transition: box-shadow 0.22s ease, background 0.3s ease;
289 | box-shadow: 0 3px 18px rgba(66, 133, 244, 0.35);
290 | display: flex;
291 | align-items: center;
292 | font-size: 1.05rem;
293 |
294 | &:hover {
295 | background: linear-gradient(90deg, #0e53a4 0%, #208bd9 100%);
296 | box-shadow: 0 6px 28px rgba(66, 133, 244, 0.5);
297 | }
298 | span {
299 | margin-right: 6px;
300 | letter-spacing: 0.6px;
301 | }
302 | svg {
303 | font-size: 1.3rem;
304 | margin-left: 8px;
305 | }
306 | }
307 | `;
308 |
309 | const Hero = styled.section`
310 | min-height: 100vh;
311 | display: flex;
312 | justify-content: center;
313 | align-items: center;
314 | padding: 0 1rem;
315 | background: linear-gradient(135deg, #eef5fb 0%, #cde6fc 100%);
316 | `;
317 |
318 | const HeroContentGlass = styled(motion.div)`
319 | background: rgba(255 255 255 / 0.3);
320 | box-shadow: 0 8px 36px rgba(0, 123, 255, 0.18);
321 | backdrop-filter: saturate(180%) blur(15px);
322 | border-radius: 28px;
323 | padding: 3.5rem 3rem;
324 | max-width: 38rem;
325 | color: #101828;
326 | text-align: center;
327 |
328 | h1 {
329 | font-size: 2.7rem;
330 | font-weight: 700;
331 | color: #003a8c;
332 | margin-bottom: 1.15rem;
333 | letter-spacing: 0.01em;
334 | user-select: none;
335 | }
336 |
337 | p {
338 | font-size: 1.21rem;
339 | margin-bottom: 2rem;
340 | font-weight: 500;
341 | color: #2455b2d9;
342 | user-select: none;
343 | }
344 |
345 | @media (max-width: 420px) {
346 | padding: 3rem 2rem;
347 | h1 {
348 | font-size: 2.1rem;
349 | }
350 | }
351 | `;
352 |
353 | const LogoContainer = styled.div`
354 | margin-top: 2rem;
355 | display: flex;
356 | justify-content: center;
357 | img {
358 | height: 1.6rem;
359 | width: auto;
360 | filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.1));
361 | }
362 | `;
363 |
364 | const About = styled.section`
365 | padding: 3rem 1rem 3rem;
366 | background: linear-gradient(135deg, #c8e1ff 0%, #f5fbff 100%);
367 | min-height: auto;
368 | display: flex;
369 | flex-direction: column;
370 |
371 | h2 {
372 | font-size: 1.7rem;
373 | font-weight: 700;
374 | margin-bottom: 2.8rem;
375 | color: #204192e8;
376 | text-align: center;
377 | letter-spacing: 0.02em;
378 | user-select: none;
379 | }
380 | `;
381 |
382 | const Features = styled.div`
383 | display: grid;
384 | grid-template-columns: repeat(auto-fit,minmax(300px,1fr));
385 | gap: 1.8rem;
386 | max-width: 1200px;
387 | margin: 0 auto;
388 | `;
389 |
390 | const FeatureGlass = styled(motion.div)`
391 | background: rgba(255 255 255 / 0.28);
392 | border-radius: 20px;
393 | padding: 1.5rem 1.7rem;
394 | box-shadow: 0 14px 40px rgba(3, 67, 251, 0.1);
395 | backdrop-filter: saturate(190%) blur(22px);
396 | border: 1.2px solid rgba(255 255 255 / 0.35);
397 | cursor: default;
398 | display: flex;
399 | flex-direction: column;
400 | transition: all 0.3s ease;
401 | min-height: 220px;
402 |
403 | h3 {
404 | color: #064091;
405 | font-weight: 700;
406 | margin: 0.4rem 0 1rem 0;
407 | font-size: 1.12rem;
408 | letter-spacing: 0.01em;
409 | }
410 | p {
411 | color: #3755a4dd;
412 | font-weight: 500;
413 | margin: 0;
414 | font-size: 0.97rem;
415 | flex-grow: 1;
416 | }
417 | `;
418 |
419 | const FeatureIcon = styled.div`
420 | font-size: 2.3rem;
421 | color: #1862f0;
422 | user-select: none;
423 | transition: transform 0.18s ease-out;
424 |
425 | ${FeatureGlass}:hover & {
426 | transform: scale(1.25) rotate(7deg);
427 | }
428 | `;
429 |
430 | const RoadmapSection = styled.section`
431 | padding: 3rem 1.4rem 4rem;
432 | min-height: 100vh;
433 | background: linear-gradient(150deg, #dbe8ff 0%, #f8fbff 100%);
434 | display: flex;
435 | flex-direction: column;
436 | justify-content: center;
437 |
438 | h2 {
439 | font-weight: 700;
440 | font-size: 1.65rem;
441 | margin-bottom: 2.3rem;
442 | color: #004bb5cc;
443 | text-align: center;
444 | letter-spacing: 0.01em;
445 | user-select: none;
446 | }
447 | `;
448 |
449 | const Footer = styled.footer`
450 | background: rgba(255 255 255 / 0.6);
451 | backdrop-filter: saturate(180%) blur(20px);
452 | padding: 3rem 1.5rem;
453 | border-top: 1.6px solid rgba(0, 0, 0, 0.05);
454 | text-align: center;
455 | color: #3d4668dd;
456 | font-size: 0.92rem;
457 | user-select: none;
458 | `;
459 |
460 | const FooterLinks = styled.div`
461 | margin-top: 1.7rem;
462 |
463 | a {
464 | color: #2060f0dd;
465 | text-decoration: none;
466 | font-weight: 600;
467 | margin: 0 1.3rem;
468 | transition: color 0.3s ease, transform 0.3s ease;
469 |
470 | &:hover,
471 | &:focus {
472 | color: #134ac0;
473 | transform: translateY(-3px);
474 | text-decoration: underline;
475 | }
476 | }
477 | `;
478 |
479 | const PopupOverlay = styled(motion.div)`
480 | position: fixed;
481 | inset: 0;
482 | background-color: rgba(14, 17, 22, 0.71);
483 | display: flex;
484 | justify-content: center;
485 | align-items: center;
486 | z-index: 1300;
487 | `;
488 |
489 | const PopupContent = styled(motion.div)`
490 | background: rgba(255 255 255 / 0.9);
491 | width: 90%;
492 | max-width: 480px;
493 | border-radius: 22px;
494 | padding: 2rem 2.4rem;
495 | box-shadow: 0 14px 50px rgb(33 111 242 / 0.3);
496 | backdrop-filter: saturate(150%) blur(24px);
497 | position: relative;
498 |
499 | h2 {
500 | color: #1044a4;
501 | margin-bottom: 1.2rem;
502 | font-weight: 700;
503 | font-size: 1.5rem;
504 | user-select: none;
505 | }
506 |
507 | p {
508 | color: #2d2f33dd;
509 | line-height: 1.65;
510 | font-weight: 500;
511 | }
512 | `;
513 |
514 | const PopupCloseButton = styled.button`
515 | position: absolute;
516 | top: 14px;
517 | right: 14px;
518 | background: transparent;
519 | border: none;
520 | font-size: 2rem;
521 | line-height: 1;
522 | cursor: pointer;
523 | color: #0c52a4;
524 | font-weight: 700;
525 | transition: color 0.2s ease;
526 |
527 | &:hover,
528 | &:focus {
529 | color: #093779;
530 | }
531 | `;
532 |
533 | const HideFullpageCredits = styled.div`
534 | .fp-watermark {
535 | display: none !important;
536 | }
537 | `;
538 |
539 | export default () => (
540 |
541 |
542 |
543 | );
544 |
--------------------------------------------------------------------------------
/src/varion_frontend/src/dashboard/dashboard.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, useRef } from "react";
2 | import styled from "styled-components";
3 | import { motion, AnimatePresence } from "framer-motion";
4 | import Patients from "./patients";
5 | import { FiHome, FiHeart, FiLogOut } from "react-icons/fi";
6 | import { FiAlertCircle } from "react-icons/fi";
7 | import { useConnect } from "@connect2ic/react";
8 | import { varion_backend } from "declarations/varion_backend";
9 | import { ResponsiveBar } from "@nivo/bar";
10 |
11 | /* --- STYLE VARIABLES FOR VARION THEME --- */
12 | const colors = {
13 | primaryGradient: "linear-gradient(90deg, #1a75ed 0%, #36aade 100%)",
14 | primaryGradientHover: "linear-gradient(90deg, #0e53a4 0%, #208bd9 100%)",
15 | primaryText: "#064091",
16 | secondaryText: "#3755a4dd",
17 | backgroundLight: "rgba(255 255 255 / 0.28)",
18 | backgroundGlass: "rgba(255 255 255 / 0.3)",
19 | backgroundLightSolid: "#edf2f7",
20 | shadowBlue: "rgba(0, 123, 255, 0.18)",
21 | shadowSubtle: "rgba(0, 0, 0, 0.05)",
22 | sidebarGradient:
23 | "linear-gradient(359.3deg, rgb(196, 214, 252) 1%, rgba(187, 187, 187, 0) 70.9%)",
24 | modalOverlay: "rgba(14, 17, 22, 0.71)",
25 | modalBackground: "rgba(255 255 255 / 0.9)",
26 | errorRed: "#ef4444",
27 | errorHoverRed: "#dc2626",
28 | white: "#fff",
29 | grayText: "#3d4668dd",
30 | lightGrayText: "#7a8793",
31 | linkBlue: "#2060f0dd",
32 | linkBlueHover: "#134ac0",
33 | };
34 |
35 | const DashboardContainer = styled.div`
36 | display: flex;
37 | height: 100vh;
38 | background: linear-gradient(135deg, #e3f2fd 0%, #ffffff 100%);
39 | font-family: "Inter", "Poppins", "Helvetica Neue", Arial, sans-serif;
40 | color: ${colors.primaryText};
41 | letter-spacing: 0.015em;
42 | `;
43 |
44 | /* SIDEBAR STYLES */
45 | const Sidebar = styled(motion.aside)`
46 | background: ${colors.sidebarGradient};
47 | min-width: 80px;
48 | height: 100%;
49 | display: flex;
50 | flex-direction: column;
51 | overflow: hidden;
52 | box-shadow: 0 6px 32px rgba(20, 40, 90, 0.15);
53 | border-right: 1.3px solid rgba(255 255 255 / 0.4);
54 | user-select: none;
55 | z-index: 1200;
56 | `;
57 |
58 | const Logo = styled(motion.div)`
59 | padding: 30px 20px;
60 | text-align: center;
61 | margin-bottom: 30px;
62 | overflow: hidden;
63 | img {
64 | height: auto;
65 | }
66 | `;
67 |
68 | const Nav = styled.nav`
69 | ul {
70 | list-style: none;
71 | padding: 0;
72 | margin: 0;
73 | }
74 | `;
75 |
76 | const NavItem = styled(motion.li)`
77 | padding: 18px 25px;
78 | cursor: pointer;
79 | display: flex;
80 | align-items: center;
81 | color: #677294;
82 | font-size: 1.15rem;
83 | font-weight: 600;
84 | border-radius: 12px;
85 | margin: 8px 15px;
86 | user-select: none;
87 | transition: all 0.25s ease;
88 |
89 | &:hover,
90 | &:focus-visible {
91 | background: rgba(3, 67, 251, 0.11);
92 | color: ${colors.primaryText};
93 | box-shadow: 0 10px 40px rgba(3, 67, 251, 0.15);
94 | outline-offset: 3px;
95 | }
96 |
97 | &.active {
98 | background: ${colors.backgroundGlass};
99 | box-shadow: 0 14px 40px rgba(3, 67, 251, 0.18);
100 | color: ${colors.primaryText};
101 | }
102 | `;
103 |
104 | const Icon = styled.span`
105 | font-size: 1.75rem;
106 | min-width: 30px;
107 | display: flex;
108 | justify-content: center;
109 | color: inherit;
110 | `;
111 |
112 | const Label = styled(motion.span)`
113 | margin-left: 15px;
114 | white-space: nowrap;
115 | color: inherit;
116 | user-select: none;
117 | `;
118 |
119 | /* MAIN CONTENT */
120 | const MainContent = styled.main`
121 | flex-grow: 1;
122 | padding: 2.25rem 3rem;
123 | overflow-y: auto;
124 | background: ${colors.white};
125 | border-radius: 28px;
126 | margin: 20px 40px 20px 20px;
127 | box-shadow: 0 8px 36px rgba(0, 123, 255, 0.18);
128 | display: flex;
129 | flex-direction: column;
130 | min-width: 0;
131 | `;
132 |
133 | /* DASHBOARD BOX */
134 | const DashboardContent = styled.section`
135 | padding: 2rem 2.5rem;
136 | background: ${colors.backgroundGlass};
137 | border-radius: 28px;
138 | box-shadow: 0 14px 50px rgb(33 111 242 / 0.3);
139 | color: ${colors.primaryText};
140 | flex-grow: 1;
141 | display: flex;
142 | flex-direction: column;
143 | `;
144 |
145 | /* CHART WRAPPER */
146 | const ChartContainer = styled.div`
147 | height: 400px;
148 | margin-bottom: 2rem;
149 | background: ${colors.backgroundLightSolid};
150 | border-radius: 15px;
151 | padding: 24px;
152 | box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.07);
153 | `;
154 |
155 | /* CHART HEADER */
156 | const ChartHeader = styled.div`
157 | display: flex;
158 | justify-content: space-between;
159 | align-items: center;
160 | margin-bottom: 1.75rem;
161 | user-select: none;
162 | `;
163 |
164 | const ChartTitle = styled.h2`
165 | font-size: 2rem;
166 | font-weight: 700;
167 | margin: 0;
168 | color: ${colors.primaryText};
169 | `;
170 |
171 | /* FORM & INPUTS */
172 | const InputContainer = styled.div`
173 | display: flex;
174 | flex-direction: column;
175 | gap: 1.5rem;
176 | background: ${colors.backgroundLightSolid};
177 | padding: 2rem 2.5rem;
178 | border-radius: 22px;
179 | box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.06);
180 | user-select: none;
181 | `;
182 |
183 | const InstructionText = styled.p`
184 | font-weight: 600;
185 | font-size: 1.125rem;
186 | margin: 0;
187 | user-select: text;
188 | color: ${colors.primaryText};
189 | `;
190 |
191 | const StyledInput = styled.input`
192 | padding: 14px 20px;
193 | border: 1.5px solid #d1d9e6;
194 | border-radius: 16px;
195 | font-size: 1rem;
196 | width: 100%;
197 | color: ${colors.primaryText};
198 | letter-spacing: 0.015em;
199 | transition: border-color 0.3s ease;
200 |
201 | &:focus {
202 | outline: none;
203 | border-color: ${colors.primaryGradientHover};
204 | box-shadow: 0 0 10px ${colors.primaryGradientHover};
205 | }
206 | `;
207 |
208 | const StyledButton = styled.button`
209 | background: ${colors.primaryGradient};
210 | color: ${colors.white};
211 | border: none;
212 | padding: 14px 28px;
213 | border-radius: 24px;
214 | font-weight: 700;
215 | font-size: 1.05rem;
216 | cursor: pointer;
217 | width: 100%;
218 | letter-spacing: 0.6px;
219 | box-shadow: 0 8px 30px rgba(66, 133, 244, 0.35);
220 | transition: background 0.3s ease, box-shadow 0.22s ease;
221 |
222 | &:hover:not(:disabled) {
223 | background: ${colors.primaryGradientHover};
224 | box-shadow: 0 12px 48px rgba(66, 133, 244, 0.5);
225 | }
226 |
227 | &:disabled {
228 | background-color: #a0aec0;
229 | cursor: not-allowed;
230 | box-shadow: none;
231 | }
232 | `;
233 |
234 | const StyledStartButton = styled(StyledButton)`
235 | background-color: #f54b9e;
236 |
237 | &:hover:not(:disabled) {
238 | background-color: #f7288d;
239 | }
240 | `;
241 |
242 | const ConfirmButton = styled(StyledButton)`
243 | width: 85%;
244 | `;
245 |
246 | const CancelButton = styled(StyledButton)`
247 | background-color: #ef4444;
248 | margin-left: 12px;
249 | width: 15%;
250 |
251 | &:hover:not(:disabled) {
252 | background-color: ${colors.errorHoverRed};
253 | }
254 | `;
255 |
256 | /* EXAMPLE TABLE */
257 | const ExampleTable = styled.table`
258 | border-collapse: separate;
259 | border-spacing: 0;
260 | width: 100%;
261 | margin-top: 0.75rem;
262 | border-radius: 12px;
263 | overflow: hidden;
264 | box-shadow: 0 0 24px rgb(33 111 242 / 0.12);
265 | user-select: none;
266 | `;
267 |
268 | const TableHeader = styled.th`
269 | background: ${colors.backgroundLightSolid};
270 | font-weight: 600;
271 | font-size: 1rem;
272 | color: ${colors.primaryText};
273 | padding: 12px 16px;
274 | text-align: center;
275 | width: ${(props) => (props.narrow ? "4%" : "16%")};
276 | border-bottom: 1.5px solid #cbd5e0;
277 |
278 | user-select: none;
279 | `;
280 |
281 | const TableCell = styled.td`
282 | padding: 12px 16px;
283 | text-align: center;
284 | font-size: 0.95rem;
285 | color: ${colors.secondaryText};
286 | width: ${(props) => (props.narrow ? "4%" : "16%")};
287 | border-bottom: 1.5px solid #cbd5e0;
288 | user-select: none;
289 |
290 | ${(props) =>
291 | props.bordered &&
292 | `
293 | border-left: 1.5px solid #cbd5e0;
294 | border-right: 1.5px solid #cbd5e0;
295 | `}
296 | `;
297 |
298 | const TableNotes = styled.p`
299 | margin-top: 1.25rem;
300 | color: ${colors.lightGrayText};
301 | font-weight: 700;
302 | font-size: 1rem;
303 | text-align: center;
304 | user-select: none;
305 | `;
306 |
307 | /* MODAL */
308 | const Modal = styled(motion.div)`
309 | position: fixed;
310 | inset: 0;
311 | background-color: ${colors.modalOverlay};
312 | display: flex;
313 | justify-content: center;
314 | align-items: center;
315 | z-index: 1400;
316 | `;
317 |
318 | const ModalContent = styled(motion.div)`
319 | background: ${colors.modalBackground};
320 | padding: 2.5rem 3rem;
321 | border-radius: 28px;
322 | box-shadow: 0 14px 50px rgb(33 111 242 / 0.3);
323 | max-width: 440px;
324 | width: 90%;
325 | text-align: center;
326 | user-select: none;
327 |
328 | p {
329 | margin: 1.25rem 0 0 0;
330 | font-weight: 700;
331 | font-size: 1.25rem;
332 | color: ${colors.primaryText};
333 | }
334 | `;
335 |
336 | const ErrorIcon = styled(FiAlertCircle)`
337 | font-size: 60px;
338 | color: ${colors.errorRed};
339 | `;
340 |
341 | const ModalButton = styled(StyledButton)`
342 | max-width: 250px;
343 | margin-top: 1.75rem;
344 | `;
345 |
346 | /* NO DATA MESSAGE */
347 | const NoDataMessage = styled.div`
348 | height: 100%;
349 | color: #718096;
350 | font-weight: 600;
351 | font-size: 1.15rem;
352 | display: flex;
353 | justify-content: center;
354 | align-items: center;
355 | user-select: none;
356 | `;
357 |
358 | /* UTILS */
359 | const maskToken = (token) => {
360 | if (!token || token.length <= 10) return "";
361 | const end = token.slice(-4);
362 | return `********${end}`;
363 | };
364 |
365 | const Dashboard = () => {
366 | const [isExpanded, setIsExpanded] = useState(false);
367 | const [activeComponent, setActiveComponent] = useState("dashboard");
368 | const [isSigningOut, setIsSigningOut] = useState(false);
369 | const { disconnect } = useConnect();
370 | const [chartData, setChartData] = useState([]);
371 | const [link, setLink] = useState("");
372 | const [token, setToken] = useState("");
373 | const [modalError, setModalError] = useState(null);
374 | const [isEditing, setIsEditing] = useState(false);
375 | const [isSubmitted, setIsSubmitted] = useState(false);
376 | const [originalLink, setOriginalLink] = useState("");
377 | const [originalToken, setOriginalToken] = useState("");
378 | const [isRunning, setIsRunning] = useState(false);
379 | const intervalRef = useRef(null);
380 | const [lastUpdateTime, setLastUpdateTime] = useState(null);
381 | const [patientData, setPatientData] = useState([]);
382 |
383 | useEffect(() => {
384 | setChartData([]);
385 | }, []);
386 |
387 | const formatTime = (date) => {
388 | if (!date) return "";
389 | return `${date.getHours().toString().padStart(2, "0")}:${date
390 | .getMinutes()
391 | .toString()
392 | .padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")}`;
393 | };
394 |
395 | /* Sidebar animation variants */
396 | const sidebarVariants = {
397 | expanded: { width: 280 },
398 | collapsed: { width: 80 },
399 | };
400 |
401 | /* Label show/hide */
402 | const labelVariants = {
403 | expanded: { opacity: 1, display: "inline" },
404 | collapsed: { opacity: 0, transitionEnd: { display: "none" } },
405 | };
406 |
407 | const riskColors = {
408 | "Low Risk": "#56f589", // Green
409 | "Medium Risk": "#ffed72", // Yellow
410 | "High Risk": "#ff7272", // Red
411 | };
412 |
413 | const getRiskLevel = (value) => {
414 | if (value < 0.5) return "Low Risk";
415 | if (value < 0.75) return "Medium Risk";
416 | return "High Risk";
417 | };
418 |
419 | const closeModal = () => {
420 | setModalError(null);
421 | };
422 |
423 | const validateApiResponse = (data) => {
424 | if (!Array.isArray(data) || data.length === 0) {
425 | return false;
426 | }
427 |
428 | const requiredFields = ["HR", "BP", "SpO2", "RESP", "TEMP", "Patient_ID"];
429 | for (const row of data) {
430 | for (const field of requiredFields) {
431 | if (!row.hasOwnProperty(field) || row[field] === "") {
432 | return false;
433 | }
434 | }
435 | }
436 | return true;
437 | };
438 |
439 | const validateInputs = async () => {
440 | if (!link || !token) {
441 | setModalError(
442 | "Please enter both the link and Authorization Bearer token."
443 | );
444 | return false;
445 | }
446 |
447 | const urlPattern = /^https:\/\/sheetdb\.io\/api\/v1\/([\w\-]+)\/?$/;
448 | if (!urlPattern.test(link)) {
449 | setModalError("Please enter a valid sheetdb.io link.");
450 | return false;
451 | }
452 |
453 | try {
454 | const response = await fetch(link, {
455 | method: "GET",
456 | headers: {
457 | Authorization: `Bearer ${token}`,
458 | },
459 | });
460 | if (!response.ok) {
461 | throw new Error("Network response was not ok");
462 | }
463 | const data = await response.json();
464 |
465 | if (!validateApiResponse(data)) {
466 | setModalError(
467 | "The data is missing required fields. Please ensure all rows contain HR, BP, SpO2, RESP, TEMP, and Patient_ID."
468 | );
469 | setLink("");
470 | setToken("");
471 | setIsSubmitted(false);
472 | return false;
473 | }
474 | return true;
475 | } catch (error) {
476 | setModalError(
477 | "An error occurred while fetching data. Please check your link and token."
478 | );
479 | setLink("");
480 | setToken("");
481 | setIsSubmitted(false);
482 | return false;
483 | }
484 | };
485 |
486 | const fetchData = async () => {
487 | try {
488 | const response = await fetch(link, {
489 | method: "GET",
490 | headers: {
491 | Authorization: `Bearer ${token}`,
492 | },
493 | });
494 |
495 | if (!response.ok) {
496 | throw new Error("Network response was not ok");
497 | }
498 |
499 | const data = await response.json();
500 |
501 | if (!validateApiResponse(data)) {
502 | throw new Error(
503 | "Some of the data is missing required fields or is empty."
504 | );
505 | }
506 |
507 | const formattedData = data
508 | .map((row) => `${row.HR},${row.BP},${row.SpO2},${row.RESP},${row.TEMP}`)
509 | .join("\n");
510 |
511 | const result = await varion_backend.prediction_result(formattedData);
512 |
513 | if (!result || !result.Success) {
514 | throw new Error("Invalid response from ML model");
515 | }
516 |
517 | const predictionValues = result.Success.split(",").map(Number);
518 |
519 | const processedPatientData = data.map((row, index) => ({
520 | id: row.Patient_ID,
521 | HR: row.HR,
522 | BP: row.BP,
523 | SpO2: row.SpO2,
524 | RESP: row.RESP,
525 | TEMP: row.TEMP,
526 | riskLevel: getRiskLevel(predictionValues[index]),
527 | cardiacProba: predictionValues[index],
528 | lastUpdated: formatTime(new Date()),
529 | }));
530 |
531 | setPatientData(processedPatientData);
532 |
533 | const riskLevelsCount = {
534 | "Low Risk": 0,
535 | "Medium Risk": 0,
536 | "High Risk": 0,
537 | };
538 |
539 | predictionValues.forEach((val) => {
540 | riskLevelsCount[getRiskLevel(val)]++;
541 | });
542 |
543 | setChartData([
544 | {
545 | id: "Risk Levels",
546 | data: [
547 | { x: "Low Risk", Patients: riskLevelsCount["Low Risk"] },
548 | { x: "Medium Risk", Patients: riskLevelsCount["Medium Risk"] },
549 | { x: "High Risk", Patients: riskLevelsCount["High Risk"] },
550 | ],
551 | },
552 | ]);
553 |
554 | setLastUpdateTime(new Date());
555 | } catch (error) {
556 | setModalError(`An error occurred: ${error.message}`);
557 | }
558 | };
559 |
560 | const handleStartStop = () => {
561 | setIsRunning((prev) => {
562 | if (prev) {
563 | clearInterval(intervalRef.current);
564 | return false;
565 | }
566 | // Start interval
567 | fetchData();
568 | intervalRef.current = setInterval(fetchData, 10000);
569 | return true;
570 | });
571 | };
572 |
573 | const handleSubmit = async () => {
574 | const valid = await validateInputs();
575 | if (valid) {
576 | setIsSubmitted(true);
577 | setIsEditing(false);
578 | }
579 | };
580 |
581 | const handleEdit = () => {
582 | setOriginalLink(link);
583 | setOriginalToken(token);
584 | setIsEditing(true);
585 | if (isRunning) handleStartStop();
586 | };
587 |
588 | const handleConfirm = async () => {
589 | const valid = await validateInputs();
590 | if (valid) {
591 | setIsEditing(false);
592 | }
593 | };
594 |
595 | const handleCancel = () => {
596 | setLink(originalLink);
597 | setToken(originalToken);
598 | setIsEditing(false);
599 | };
600 |
601 | const handleSignOut = async () => {
602 | if (isSigningOut) return;
603 | setIsSigningOut(true);
604 | try {
605 | await disconnect();
606 | } catch (e) {
607 | console.error("Error during sign out:", e);
608 | } finally {
609 | setIsSigningOut(false);
610 | }
611 | };
612 |
613 | const maskedToken = maskToken(token);
614 |
615 | /* Active nav logic */
616 | const navItems = [
617 | { key: "dashboard", icon: , label: "Dashboard" },
618 | { key: "patients", icon: , label: "Patients" },
619 | { key: "signout", icon: , label: "Sign Out" },
620 | ];
621 |
622 | /* Renders */
623 | const renderComponent = () => {
624 | switch (activeComponent) {
625 | case "dashboard":
626 | return (
627 |
628 |
629 | Real-time Patient Data Monitoring Dashboard
630 |
631 |
632 |
633 | {lastUpdateTime && (
634 |
643 | Last updated: {formatTime(lastUpdateTime)}
644 |
645 | )}
646 | {chartData.length > 0 && chartData[0].data.length > 0 ? (
647 | riskColors[data.x]}
656 | borderColor={{ from: "color", modifiers: [["darker", 1.6]] }}
657 | axisTop={null}
658 | axisRight={null}
659 | axisBottom={{
660 | tickSize: 5,
661 | tickPadding: 5,
662 | tickRotation: 0,
663 | legend: "Cardiac Risk Level",
664 | legendPosition: "middle",
665 | legendOffset: 40,
666 | }}
667 | axisLeft={{
668 | tickSize: 5,
669 | tickPadding: 5,
670 | tickRotation: 0,
671 | legend: "Patient Count",
672 | legendPosition: "middle",
673 | legendOffset: -40,
674 | format: (d) => (Number.isInteger(d) ? d : ""),
675 | tickValues: (() => {
676 | const maxPatients = Math.max(
677 | ...chartData[0].data.map((d) => d.Patients)
678 | );
679 | if (maxPatients <= 10) return undefined;
680 | const interval = Math.ceil(maxPatients / 10);
681 | return Array.from(
682 | { length: Math.floor(maxPatients / interval) + 1 },
683 | (_, i) => i * interval
684 | );
685 | })(),
686 | }}
687 | labelSkipWidth={12}
688 | labelSkipHeight={12}
689 | labelTextColor={{ from: "color", modifiers: [["darker", 1.6]] }}
690 | animate={true}
691 | motionStiffness={90}
692 | motionDamping={15}
693 | label={(d) => `${d.value}`}
694 | />
695 | ) : (
696 | Data not available
697 | )}
698 |
699 |
700 |
701 | {isSubmitted && !isEditing ? (
702 | <>
703 | Currently streaming data from:
704 |
705 | Link: {link}
706 |
707 |
708 | Token: {maskedToken}
709 |
710 |
711 | Edit
712 |
713 |
714 |
715 | {isRunning ? "Stop ML Model" : "Start ML Model"}
716 |
717 |
718 | >
719 | ) : (
720 | <>
721 |
722 | Please provide a sheetdb.io link and its
723 | authorization bearer token to access the Spreadsheet:
724 |
725 |
726 | setLink(e.target.value)}
730 | placeholder="Enter Link"
731 | autoComplete="off"
732 | />
733 | setToken(e.target.value)}
737 | placeholder="Enter Token"
738 | autoComplete="off"
739 | />
740 |
741 | {isEditing ? (
742 |
743 | Confirm
744 | Cancel
745 |
746 | ) : (
747 |
752 | Submit
753 |
754 | )}
755 |
756 | {(!isSubmitted || isEditing) && (
757 | <>
758 |
766 |
767 | Please format your Google Spreadsheet according to
768 | the following template:
769 |
770 |
772 | window.open(
773 | "https://docs.google.com/spreadsheets/d/18gAB_iD_hw_k0BPA0kM2vMGcrSAGnO470w0ruqwKUEE/edit?usp=sharing",
774 | "_blank"
775 | )
776 | }
777 | style={{
778 | padding: "8px 16px",
779 | backgroundColor: "#357bfd",
780 | color: "white",
781 | border: "none",
782 | borderRadius: "8px",
783 | cursor: "pointer",
784 | fontSize: "14px",
785 | transition: "background-color 0.3s",
786 | fontWeight: 700,
787 | userSelect: "none",
788 | whiteSpace: "nowrap",
789 | marginLeft: "15px",
790 | }}
791 | onMouseOver={(e) => (e.target.style.backgroundColor = "#0d60f9")}
792 | onMouseOut={(e) => (e.target.style.backgroundColor = "#357bfd")}
793 | aria-label="Open example spreadsheet template"
794 | >
795 | Example Template
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 | A
804 | B
805 | C
806 | D
807 | E
808 | F
809 |
810 |
811 |
812 |
813 |
814 | 1
815 |
816 |
817 | HR
818 |
819 | BP
820 | SpO2
821 | RESP
822 | TEMP
823 | Patient_ID
824 |
825 |
826 |
827 | 2
828 |
829 | 72
830 | 120
831 | 98
832 | 16
833 | 36.5
834 | 101
835 |
836 |
837 |
838 | 3
839 |
840 | 75
841 | 118
842 | 97
843 | 18
844 | 36.7
845 | 102
846 |
847 |
848 |
849 | 4
850 |
851 | ...
852 | ...
853 | ...
854 | ...
855 | ...
856 | ...
857 |
858 |
859 |
860 | 5
861 |
862 | ...
863 | ...
864 | ...
865 | ...
866 | ...
867 | ...
868 |
869 |
870 |
871 |
872 | HR: Heart Rate, BP: Systolic Blood Pressure, SpO2: Oxygen
873 | Saturation, RESP: Respiration Rate, TEMP: Temperature
874 |
875 | >
876 | )}
877 | >
878 | )}
879 |
880 |
881 | );
882 |
883 | case "patients":
884 | return ;
885 |
886 | default:
887 | return (
888 |
889 | Dashboard Content
890 |
891 | );
892 | }
893 | };
894 |
895 | return (
896 | <>
897 |
898 | setIsExpanded(true)}
904 | onHoverEnd={() => setIsExpanded(false)}
905 | aria-label="Sidebar navigation"
906 | >
907 |
908 |
909 | {isExpanded ? (
910 |
921 | ) : (
922 |
933 | )}
934 |
935 |
936 |
937 |
938 |
939 | {navItems.map(({ key, icon, label }) => {
940 | if (key === "signout") {
941 | return (
942 |
950 | {icon}
951 |
956 | {label}
957 |
958 |
959 | );
960 | }
961 | return (
962 | setActiveComponent(key)}
965 | whileTap={{ scale: 0.95 }}
966 | className={activeComponent === key ? "active" : ""}
967 | role="button"
968 | tabIndex={0}
969 | aria-current={activeComponent === key ? "page" : undefined}
970 | aria-label={label}
971 | >
972 | {icon}
973 |
978 | {label}
979 |
980 |
981 | );
982 | })}
983 |
984 |
985 |
986 |
987 | {renderComponent()}
988 |
989 |
990 |
991 | {modalError && (
992 |
1001 |
1006 |
1007 | {modalError}
1008 |
1009 | Got it
1010 |
1011 |
1012 |
1013 | )}
1014 |
1015 | >
1016 | );
1017 | };
1018 |
1019 | export default Dashboard;
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "adler2"
7 | version = "2.0.0"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
10 |
11 | [[package]]
12 | name = "ahash"
13 | version = "0.8.11"
14 | source = "registry+https://github.com/rust-lang/crates.io-index"
15 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
16 | dependencies = [
17 | "cfg-if",
18 | "once_cell",
19 | "version_check",
20 | "zerocopy",
21 | ]
22 |
23 | [[package]]
24 | name = "aho-corasick"
25 | version = "1.1.3"
26 | source = "registry+https://github.com/rust-lang/crates.io-index"
27 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
28 | dependencies = [
29 | "memchr",
30 | ]
31 |
32 | [[package]]
33 | name = "anyhow"
34 | version = "1.0.86"
35 | source = "registry+https://github.com/rust-lang/crates.io-index"
36 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
37 |
38 | [[package]]
39 | name = "anymap2"
40 | version = "0.13.0"
41 | source = "registry+https://github.com/rust-lang/crates.io-index"
42 | checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
43 |
44 | [[package]]
45 | name = "arrayvec"
46 | version = "0.5.2"
47 | source = "registry+https://github.com/rust-lang/crates.io-index"
48 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
49 |
50 | [[package]]
51 | name = "autocfg"
52 | version = "1.3.0"
53 | source = "registry+https://github.com/rust-lang/crates.io-index"
54 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
55 |
56 | [[package]]
57 | name = "binread"
58 | version = "2.2.0"
59 | source = "registry+https://github.com/rust-lang/crates.io-index"
60 | checksum = "16598dfc8e6578e9b597d9910ba2e73618385dc9f4b1d43dd92c349d6be6418f"
61 | dependencies = [
62 | "binread_derive",
63 | "lazy_static",
64 | "rustversion",
65 | ]
66 |
67 | [[package]]
68 | name = "binread_derive"
69 | version = "2.1.0"
70 | source = "registry+https://github.com/rust-lang/crates.io-index"
71 | checksum = "1d9672209df1714ee804b1f4d4f68c8eb2a90b1f7a07acf472f88ce198ef1fed"
72 | dependencies = [
73 | "either",
74 | "proc-macro2",
75 | "quote",
76 | "syn 1.0.109",
77 | ]
78 |
79 | [[package]]
80 | name = "bit-set"
81 | version = "0.5.3"
82 | source = "registry+https://github.com/rust-lang/crates.io-index"
83 | checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
84 | dependencies = [
85 | "bit-vec",
86 | ]
87 |
88 | [[package]]
89 | name = "bit-vec"
90 | version = "0.6.3"
91 | source = "registry+https://github.com/rust-lang/crates.io-index"
92 | checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
93 |
94 | [[package]]
95 | name = "bitflags"
96 | version = "2.6.0"
97 | source = "registry+https://github.com/rust-lang/crates.io-index"
98 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
99 |
100 | [[package]]
101 | name = "block-buffer"
102 | version = "0.10.4"
103 | source = "registry+https://github.com/rust-lang/crates.io-index"
104 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
105 | dependencies = [
106 | "generic-array",
107 | ]
108 |
109 | [[package]]
110 | name = "byteorder"
111 | version = "1.5.0"
112 | source = "registry+https://github.com/rust-lang/crates.io-index"
113 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
114 |
115 | [[package]]
116 | name = "bytes"
117 | version = "1.7.1"
118 | source = "registry+https://github.com/rust-lang/crates.io-index"
119 | checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
120 |
121 | [[package]]
122 | name = "candid"
123 | version = "0.10.10"
124 | source = "registry+https://github.com/rust-lang/crates.io-index"
125 | checksum = "6c30ee7f886f296b6422c0ff017e89dd4f831521dfdcc76f3f71aae1ce817222"
126 | dependencies = [
127 | "anyhow",
128 | "binread",
129 | "byteorder",
130 | "candid_derive",
131 | "hex",
132 | "ic_principal",
133 | "leb128",
134 | "num-bigint",
135 | "num-traits",
136 | "paste",
137 | "pretty",
138 | "serde",
139 | "serde_bytes",
140 | "stacker",
141 | "thiserror",
142 | ]
143 |
144 | [[package]]
145 | name = "candid_derive"
146 | version = "0.6.6"
147 | source = "registry+https://github.com/rust-lang/crates.io-index"
148 | checksum = "3de398570c386726e7a59d9887b68763c481477f9a043fb998a2e09d428df1a9"
149 | dependencies = [
150 | "lazy_static",
151 | "proc-macro2",
152 | "quote",
153 | "syn 2.0.76",
154 | ]
155 |
156 | [[package]]
157 | name = "cc"
158 | version = "1.1.14"
159 | source = "registry+https://github.com/rust-lang/crates.io-index"
160 | checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932"
161 | dependencies = [
162 | "shlex",
163 | ]
164 |
165 | [[package]]
166 | name = "cfg-if"
167 | version = "1.0.0"
168 | source = "registry+https://github.com/rust-lang/crates.io-index"
169 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
170 |
171 | [[package]]
172 | name = "cpufeatures"
173 | version = "0.2.13"
174 | source = "registry+https://github.com/rust-lang/crates.io-index"
175 | checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
176 | dependencies = [
177 | "libc",
178 | ]
179 |
180 | [[package]]
181 | name = "crc32fast"
182 | version = "1.4.2"
183 | source = "registry+https://github.com/rust-lang/crates.io-index"
184 | checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
185 | dependencies = [
186 | "cfg-if",
187 | ]
188 |
189 | [[package]]
190 | name = "crossbeam-deque"
191 | version = "0.8.5"
192 | source = "registry+https://github.com/rust-lang/crates.io-index"
193 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
194 | dependencies = [
195 | "crossbeam-epoch",
196 | "crossbeam-utils",
197 | ]
198 |
199 | [[package]]
200 | name = "crossbeam-epoch"
201 | version = "0.9.18"
202 | source = "registry+https://github.com/rust-lang/crates.io-index"
203 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
204 | dependencies = [
205 | "crossbeam-utils",
206 | ]
207 |
208 | [[package]]
209 | name = "crossbeam-utils"
210 | version = "0.8.20"
211 | source = "registry+https://github.com/rust-lang/crates.io-index"
212 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
213 |
214 | [[package]]
215 | name = "crunchy"
216 | version = "0.2.2"
217 | source = "registry+https://github.com/rust-lang/crates.io-index"
218 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
219 |
220 | [[package]]
221 | name = "crypto-common"
222 | version = "0.1.6"
223 | source = "registry+https://github.com/rust-lang/crates.io-index"
224 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
225 | dependencies = [
226 | "generic-array",
227 | "typenum",
228 | ]
229 |
230 | [[package]]
231 | name = "data-encoding"
232 | version = "2.6.0"
233 | source = "registry+https://github.com/rust-lang/crates.io-index"
234 | checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
235 |
236 | [[package]]
237 | name = "deranged"
238 | version = "0.3.11"
239 | source = "registry+https://github.com/rust-lang/crates.io-index"
240 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
241 | dependencies = [
242 | "powerfmt",
243 | ]
244 |
245 | [[package]]
246 | name = "derive-new"
247 | version = "0.5.9"
248 | source = "registry+https://github.com/rust-lang/crates.io-index"
249 | checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
250 | dependencies = [
251 | "proc-macro2",
252 | "quote",
253 | "syn 1.0.109",
254 | ]
255 |
256 | [[package]]
257 | name = "digest"
258 | version = "0.10.7"
259 | source = "registry+https://github.com/rust-lang/crates.io-index"
260 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
261 | dependencies = [
262 | "block-buffer",
263 | "crypto-common",
264 | ]
265 |
266 | [[package]]
267 | name = "doc-comment"
268 | version = "0.3.3"
269 | source = "registry+https://github.com/rust-lang/crates.io-index"
270 | checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
271 |
272 | [[package]]
273 | name = "downcast-rs"
274 | version = "1.2.1"
275 | source = "registry+https://github.com/rust-lang/crates.io-index"
276 | checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
277 |
278 | [[package]]
279 | name = "dyn-clone"
280 | version = "1.0.17"
281 | source = "registry+https://github.com/rust-lang/crates.io-index"
282 | checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
283 |
284 | [[package]]
285 | name = "dyn-hash"
286 | version = "0.2.0"
287 | source = "registry+https://github.com/rust-lang/crates.io-index"
288 | checksum = "a650a461c6a8ff1ef205ed9a2ad56579309853fecefc2423f73dced342f92258"
289 |
290 | [[package]]
291 | name = "either"
292 | version = "1.13.0"
293 | source = "registry+https://github.com/rust-lang/crates.io-index"
294 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
295 |
296 | [[package]]
297 | name = "errno"
298 | version = "0.3.9"
299 | source = "registry+https://github.com/rust-lang/crates.io-index"
300 | checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
301 | dependencies = [
302 | "libc",
303 | "windows-sys 0.52.0",
304 | ]
305 |
306 | [[package]]
307 | name = "filetime"
308 | version = "0.2.24"
309 | source = "registry+https://github.com/rust-lang/crates.io-index"
310 | checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550"
311 | dependencies = [
312 | "cfg-if",
313 | "libc",
314 | "libredox",
315 | "windows-sys 0.59.0",
316 | ]
317 |
318 | [[package]]
319 | name = "flate2"
320 | version = "1.0.33"
321 | source = "registry+https://github.com/rust-lang/crates.io-index"
322 | checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
323 | dependencies = [
324 | "crc32fast",
325 | "miniz_oxide",
326 | ]
327 |
328 | [[package]]
329 | name = "futures"
330 | version = "0.3.30"
331 | source = "registry+https://github.com/rust-lang/crates.io-index"
332 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
333 | dependencies = [
334 | "futures-channel",
335 | "futures-core",
336 | "futures-executor",
337 | "futures-io",
338 | "futures-sink",
339 | "futures-task",
340 | "futures-util",
341 | ]
342 |
343 | [[package]]
344 | name = "futures-channel"
345 | version = "0.3.30"
346 | source = "registry+https://github.com/rust-lang/crates.io-index"
347 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
348 | dependencies = [
349 | "futures-core",
350 | "futures-sink",
351 | ]
352 |
353 | [[package]]
354 | name = "futures-core"
355 | version = "0.3.30"
356 | source = "registry+https://github.com/rust-lang/crates.io-index"
357 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
358 |
359 | [[package]]
360 | name = "futures-executor"
361 | version = "0.3.30"
362 | source = "registry+https://github.com/rust-lang/crates.io-index"
363 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
364 | dependencies = [
365 | "futures-core",
366 | "futures-task",
367 | "futures-util",
368 | ]
369 |
370 | [[package]]
371 | name = "futures-io"
372 | version = "0.3.30"
373 | source = "registry+https://github.com/rust-lang/crates.io-index"
374 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
375 |
376 | [[package]]
377 | name = "futures-macro"
378 | version = "0.3.30"
379 | source = "registry+https://github.com/rust-lang/crates.io-index"
380 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
381 | dependencies = [
382 | "proc-macro2",
383 | "quote",
384 | "syn 2.0.76",
385 | ]
386 |
387 | [[package]]
388 | name = "futures-sink"
389 | version = "0.3.30"
390 | source = "registry+https://github.com/rust-lang/crates.io-index"
391 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
392 |
393 | [[package]]
394 | name = "futures-task"
395 | version = "0.3.30"
396 | source = "registry+https://github.com/rust-lang/crates.io-index"
397 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
398 |
399 | [[package]]
400 | name = "futures-util"
401 | version = "0.3.30"
402 | source = "registry+https://github.com/rust-lang/crates.io-index"
403 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
404 | dependencies = [
405 | "futures-channel",
406 | "futures-core",
407 | "futures-io",
408 | "futures-macro",
409 | "futures-sink",
410 | "futures-task",
411 | "memchr",
412 | "pin-project-lite",
413 | "pin-utils",
414 | "slab",
415 | ]
416 |
417 | [[package]]
418 | name = "generic-array"
419 | version = "0.14.7"
420 | source = "registry+https://github.com/rust-lang/crates.io-index"
421 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
422 | dependencies = [
423 | "typenum",
424 | "version_check",
425 | ]
426 |
427 | [[package]]
428 | name = "getrandom"
429 | version = "0.2.15"
430 | source = "registry+https://github.com/rust-lang/crates.io-index"
431 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
432 | dependencies = [
433 | "cfg-if",
434 | "libc",
435 | "wasi",
436 | ]
437 |
438 | [[package]]
439 | name = "half"
440 | version = "2.4.1"
441 | source = "registry+https://github.com/rust-lang/crates.io-index"
442 | checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
443 | dependencies = [
444 | "cfg-if",
445 | "crunchy",
446 | "num-traits",
447 | ]
448 |
449 | [[package]]
450 | name = "hashbrown"
451 | version = "0.14.5"
452 | source = "registry+https://github.com/rust-lang/crates.io-index"
453 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
454 | dependencies = [
455 | "ahash",
456 | ]
457 |
458 | [[package]]
459 | name = "hex"
460 | version = "0.4.3"
461 | source = "registry+https://github.com/rust-lang/crates.io-index"
462 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
463 |
464 | [[package]]
465 | name = "ic-cdk"
466 | version = "0.13.5"
467 | source = "registry+https://github.com/rust-lang/crates.io-index"
468 | checksum = "3b1da6a25b045f9da3c9459c0cb2b0700ac368ee16382975a17185a23b9c18ab"
469 | dependencies = [
470 | "candid",
471 | "ic-cdk-macros 0.13.2",
472 | "ic0 0.21.1",
473 | "serde",
474 | "serde_bytes",
475 | ]
476 |
477 | [[package]]
478 | name = "ic-cdk"
479 | version = "0.15.1"
480 | source = "registry+https://github.com/rust-lang/crates.io-index"
481 | checksum = "038ff230bf0fc8630943e3c52e989d248a7c89834ccb65da408fabc5817a475b"
482 | dependencies = [
483 | "candid",
484 | "ic-cdk-macros 0.15.0",
485 | "ic0 0.23.0",
486 | "serde",
487 | "serde_bytes",
488 | ]
489 |
490 | [[package]]
491 | name = "ic-cdk-macros"
492 | version = "0.13.2"
493 | source = "registry+https://github.com/rust-lang/crates.io-index"
494 | checksum = "a45800053d80a6df839a71aaea5797e723188c0b992618208ca3b941350c7355"
495 | dependencies = [
496 | "candid",
497 | "proc-macro2",
498 | "quote",
499 | "serde",
500 | "serde_tokenstream 0.1.7",
501 | "syn 1.0.109",
502 | ]
503 |
504 | [[package]]
505 | name = "ic-cdk-macros"
506 | version = "0.15.0"
507 | source = "registry+https://github.com/rust-lang/crates.io-index"
508 | checksum = "3af44fb4ec3a4b18831c9d3303ca8fa2ace846c4022d50cb8df4122635d3782e"
509 | dependencies = [
510 | "candid",
511 | "proc-macro2",
512 | "quote",
513 | "serde",
514 | "serde_tokenstream 0.2.2",
515 | "syn 2.0.76",
516 | ]
517 |
518 | [[package]]
519 | name = "ic-cdk-timers"
520 | version = "0.7.0"
521 | source = "registry+https://github.com/rust-lang/crates.io-index"
522 | checksum = "054727a3a1c486528b96349817d54290ff70df6addf417def456ea708a16f7fb"
523 | dependencies = [
524 | "futures",
525 | "ic-cdk 0.13.5",
526 | "ic0 0.21.1",
527 | "serde",
528 | "serde_bytes",
529 | "slotmap",
530 | ]
531 |
532 | [[package]]
533 | name = "ic0"
534 | version = "0.21.1"
535 | source = "registry+https://github.com/rust-lang/crates.io-index"
536 | checksum = "a54b5297861c651551676e8c43df805dad175cc33bc97dbd992edbbb85dcbcdf"
537 |
538 | [[package]]
539 | name = "ic0"
540 | version = "0.23.0"
541 | source = "registry+https://github.com/rust-lang/crates.io-index"
542 | checksum = "8de254dd67bbd58073e23dc1c8553ba12fa1dc610a19de94ad2bbcd0460c067f"
543 |
544 | [[package]]
545 | name = "ic_principal"
546 | version = "0.1.1"
547 | source = "registry+https://github.com/rust-lang/crates.io-index"
548 | checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c"
549 | dependencies = [
550 | "crc32fast",
551 | "data-encoding",
552 | "serde",
553 | "sha2",
554 | "thiserror",
555 | ]
556 |
557 | [[package]]
558 | name = "itertools"
559 | version = "0.10.5"
560 | source = "registry+https://github.com/rust-lang/crates.io-index"
561 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
562 | dependencies = [
563 | "either",
564 | ]
565 |
566 | [[package]]
567 | name = "itertools"
568 | version = "0.12.1"
569 | source = "registry+https://github.com/rust-lang/crates.io-index"
570 | checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
571 | dependencies = [
572 | "either",
573 | ]
574 |
575 | [[package]]
576 | name = "itertools"
577 | version = "0.13.0"
578 | source = "registry+https://github.com/rust-lang/crates.io-index"
579 | checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
580 | dependencies = [
581 | "either",
582 | ]
583 |
584 | [[package]]
585 | name = "itoa"
586 | version = "1.0.11"
587 | source = "registry+https://github.com/rust-lang/crates.io-index"
588 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
589 |
590 | [[package]]
591 | name = "kstring"
592 | version = "2.0.2"
593 | source = "registry+https://github.com/rust-lang/crates.io-index"
594 | checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1"
595 | dependencies = [
596 | "serde",
597 | "static_assertions",
598 | ]
599 |
600 | [[package]]
601 | name = "lazy_static"
602 | version = "1.5.0"
603 | source = "registry+https://github.com/rust-lang/crates.io-index"
604 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
605 |
606 | [[package]]
607 | name = "leb128"
608 | version = "0.2.5"
609 | source = "registry+https://github.com/rust-lang/crates.io-index"
610 | checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
611 |
612 | [[package]]
613 | name = "libc"
614 | version = "0.2.158"
615 | source = "registry+https://github.com/rust-lang/crates.io-index"
616 | checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
617 |
618 | [[package]]
619 | name = "libm"
620 | version = "0.2.8"
621 | source = "registry+https://github.com/rust-lang/crates.io-index"
622 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
623 |
624 | [[package]]
625 | name = "libredox"
626 | version = "0.1.3"
627 | source = "registry+https://github.com/rust-lang/crates.io-index"
628 | checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
629 | dependencies = [
630 | "bitflags",
631 | "libc",
632 | "redox_syscall",
633 | ]
634 |
635 | [[package]]
636 | name = "linux-raw-sys"
637 | version = "0.4.14"
638 | source = "registry+https://github.com/rust-lang/crates.io-index"
639 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
640 |
641 | [[package]]
642 | name = "liquid"
643 | version = "0.26.9"
644 | source = "registry+https://github.com/rust-lang/crates.io-index"
645 | checksum = "7cdcc72b82748f47c2933c172313f5a9aea5b2c4eb3fa4c66b4ea55bb60bb4b1"
646 | dependencies = [
647 | "doc-comment",
648 | "liquid-core",
649 | "liquid-derive",
650 | "liquid-lib",
651 | "serde",
652 | ]
653 |
654 | [[package]]
655 | name = "liquid-core"
656 | version = "0.26.9"
657 | source = "registry+https://github.com/rust-lang/crates.io-index"
658 | checksum = "2752e978ffc53670f3f2e8b3ef09f348d6f7b5474a3be3f8a5befe5382e4effb"
659 | dependencies = [
660 | "anymap2",
661 | "itertools 0.13.0",
662 | "kstring",
663 | "liquid-derive",
664 | "num-traits",
665 | "pest",
666 | "pest_derive",
667 | "regex",
668 | "serde",
669 | "time",
670 | ]
671 |
672 | [[package]]
673 | name = "liquid-derive"
674 | version = "0.26.8"
675 | source = "registry+https://github.com/rust-lang/crates.io-index"
676 | checksum = "3b51f1d220e3fa869e24cfd75915efe3164bd09bb11b3165db3f37f57bf673e3"
677 | dependencies = [
678 | "proc-macro2",
679 | "quote",
680 | "syn 2.0.76",
681 | ]
682 |
683 | [[package]]
684 | name = "liquid-lib"
685 | version = "0.26.9"
686 | source = "registry+https://github.com/rust-lang/crates.io-index"
687 | checksum = "59b1a298d3d2287ee5b1e43840d885b8fdfc37d3f4e90d82aacfd04d021618da"
688 | dependencies = [
689 | "itertools 0.13.0",
690 | "liquid-core",
691 | "once_cell",
692 | "percent-encoding",
693 | "regex",
694 | "time",
695 | "unicode-segmentation",
696 | ]
697 |
698 | [[package]]
699 | name = "log"
700 | version = "0.4.22"
701 | source = "registry+https://github.com/rust-lang/crates.io-index"
702 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
703 |
704 | [[package]]
705 | name = "maplit"
706 | version = "1.0.2"
707 | source = "registry+https://github.com/rust-lang/crates.io-index"
708 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
709 |
710 | [[package]]
711 | name = "matrixmultiply"
712 | version = "0.3.9"
713 | source = "registry+https://github.com/rust-lang/crates.io-index"
714 | checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a"
715 | dependencies = [
716 | "autocfg",
717 | "rawpointer",
718 | ]
719 |
720 | [[package]]
721 | name = "memchr"
722 | version = "2.7.4"
723 | source = "registry+https://github.com/rust-lang/crates.io-index"
724 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
725 |
726 | [[package]]
727 | name = "memmap2"
728 | version = "0.9.4"
729 | source = "registry+https://github.com/rust-lang/crates.io-index"
730 | checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322"
731 | dependencies = [
732 | "libc",
733 | ]
734 |
735 | [[package]]
736 | name = "minimal-lexical"
737 | version = "0.2.1"
738 | source = "registry+https://github.com/rust-lang/crates.io-index"
739 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
740 |
741 | [[package]]
742 | name = "miniz_oxide"
743 | version = "0.8.0"
744 | source = "registry+https://github.com/rust-lang/crates.io-index"
745 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
746 | dependencies = [
747 | "adler2",
748 | ]
749 |
750 | [[package]]
751 | name = "ndarray"
752 | version = "0.15.6"
753 | source = "registry+https://github.com/rust-lang/crates.io-index"
754 | checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
755 | dependencies = [
756 | "matrixmultiply",
757 | "num-complex",
758 | "num-integer",
759 | "num-traits",
760 | "rawpointer",
761 | ]
762 |
763 | [[package]]
764 | name = "nom"
765 | version = "7.1.3"
766 | source = "registry+https://github.com/rust-lang/crates.io-index"
767 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
768 | dependencies = [
769 | "memchr",
770 | "minimal-lexical",
771 | ]
772 |
773 | [[package]]
774 | name = "num-bigint"
775 | version = "0.4.6"
776 | source = "registry+https://github.com/rust-lang/crates.io-index"
777 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
778 | dependencies = [
779 | "num-integer",
780 | "num-traits",
781 | "serde",
782 | ]
783 |
784 | [[package]]
785 | name = "num-complex"
786 | version = "0.4.6"
787 | source = "registry+https://github.com/rust-lang/crates.io-index"
788 | checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
789 | dependencies = [
790 | "num-traits",
791 | ]
792 |
793 | [[package]]
794 | name = "num-conv"
795 | version = "0.1.0"
796 | source = "registry+https://github.com/rust-lang/crates.io-index"
797 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
798 |
799 | [[package]]
800 | name = "num-integer"
801 | version = "0.1.46"
802 | source = "registry+https://github.com/rust-lang/crates.io-index"
803 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
804 | dependencies = [
805 | "num-traits",
806 | ]
807 |
808 | [[package]]
809 | name = "num-traits"
810 | version = "0.2.19"
811 | source = "registry+https://github.com/rust-lang/crates.io-index"
812 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
813 | dependencies = [
814 | "autocfg",
815 | "libm",
816 | ]
817 |
818 | [[package]]
819 | name = "once_cell"
820 | version = "1.19.0"
821 | source = "registry+https://github.com/rust-lang/crates.io-index"
822 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
823 |
824 | [[package]]
825 | name = "paste"
826 | version = "1.0.15"
827 | source = "registry+https://github.com/rust-lang/crates.io-index"
828 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
829 |
830 | [[package]]
831 | name = "percent-encoding"
832 | version = "2.3.1"
833 | source = "registry+https://github.com/rust-lang/crates.io-index"
834 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
835 |
836 | [[package]]
837 | name = "pest"
838 | version = "2.7.11"
839 | source = "registry+https://github.com/rust-lang/crates.io-index"
840 | checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95"
841 | dependencies = [
842 | "memchr",
843 | "thiserror",
844 | "ucd-trie",
845 | ]
846 |
847 | [[package]]
848 | name = "pest_derive"
849 | version = "2.7.11"
850 | source = "registry+https://github.com/rust-lang/crates.io-index"
851 | checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a"
852 | dependencies = [
853 | "pest",
854 | "pest_generator",
855 | ]
856 |
857 | [[package]]
858 | name = "pest_generator"
859 | version = "2.7.11"
860 | source = "registry+https://github.com/rust-lang/crates.io-index"
861 | checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183"
862 | dependencies = [
863 | "pest",
864 | "pest_meta",
865 | "proc-macro2",
866 | "quote",
867 | "syn 2.0.76",
868 | ]
869 |
870 | [[package]]
871 | name = "pest_meta"
872 | version = "2.7.11"
873 | source = "registry+https://github.com/rust-lang/crates.io-index"
874 | checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f"
875 | dependencies = [
876 | "once_cell",
877 | "pest",
878 | "sha2",
879 | ]
880 |
881 | [[package]]
882 | name = "pin-project-lite"
883 | version = "0.2.14"
884 | source = "registry+https://github.com/rust-lang/crates.io-index"
885 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
886 |
887 | [[package]]
888 | name = "pin-utils"
889 | version = "0.1.0"
890 | source = "registry+https://github.com/rust-lang/crates.io-index"
891 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
892 |
893 | [[package]]
894 | name = "powerfmt"
895 | version = "0.2.0"
896 | source = "registry+https://github.com/rust-lang/crates.io-index"
897 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
898 |
899 | [[package]]
900 | name = "ppv-lite86"
901 | version = "0.2.20"
902 | source = "registry+https://github.com/rust-lang/crates.io-index"
903 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
904 | dependencies = [
905 | "zerocopy",
906 | ]
907 |
908 | [[package]]
909 | name = "pretty"
910 | version = "0.12.3"
911 | source = "registry+https://github.com/rust-lang/crates.io-index"
912 | checksum = "b55c4d17d994b637e2f4daf6e5dc5d660d209d5642377d675d7a1c3ab69fa579"
913 | dependencies = [
914 | "arrayvec",
915 | "typed-arena",
916 | "unicode-width",
917 | ]
918 |
919 | [[package]]
920 | name = "primal-check"
921 | version = "0.3.4"
922 | source = "registry+https://github.com/rust-lang/crates.io-index"
923 | checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08"
924 | dependencies = [
925 | "num-integer",
926 | ]
927 |
928 | [[package]]
929 | name = "proc-macro2"
930 | version = "1.0.86"
931 | source = "registry+https://github.com/rust-lang/crates.io-index"
932 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
933 | dependencies = [
934 | "unicode-ident",
935 | ]
936 |
937 | [[package]]
938 | name = "prost"
939 | version = "0.11.9"
940 | source = "registry+https://github.com/rust-lang/crates.io-index"
941 | checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd"
942 | dependencies = [
943 | "bytes",
944 | "prost-derive",
945 | ]
946 |
947 | [[package]]
948 | name = "prost-derive"
949 | version = "0.11.9"
950 | source = "registry+https://github.com/rust-lang/crates.io-index"
951 | checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4"
952 | dependencies = [
953 | "anyhow",
954 | "itertools 0.10.5",
955 | "proc-macro2",
956 | "quote",
957 | "syn 1.0.109",
958 | ]
959 |
960 | [[package]]
961 | name = "psm"
962 | version = "0.1.21"
963 | source = "registry+https://github.com/rust-lang/crates.io-index"
964 | checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874"
965 | dependencies = [
966 | "cc",
967 | ]
968 |
969 | [[package]]
970 | name = "quote"
971 | version = "1.0.37"
972 | source = "registry+https://github.com/rust-lang/crates.io-index"
973 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
974 | dependencies = [
975 | "proc-macro2",
976 | ]
977 |
978 | [[package]]
979 | name = "rand"
980 | version = "0.8.5"
981 | source = "registry+https://github.com/rust-lang/crates.io-index"
982 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
983 | dependencies = [
984 | "libc",
985 | "rand_chacha",
986 | "rand_core",
987 | ]
988 |
989 | [[package]]
990 | name = "rand_chacha"
991 | version = "0.3.1"
992 | source = "registry+https://github.com/rust-lang/crates.io-index"
993 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
994 | dependencies = [
995 | "ppv-lite86",
996 | "rand_core",
997 | ]
998 |
999 | [[package]]
1000 | name = "rand_core"
1001 | version = "0.6.4"
1002 | source = "registry+https://github.com/rust-lang/crates.io-index"
1003 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
1004 | dependencies = [
1005 | "getrandom",
1006 | ]
1007 |
1008 | [[package]]
1009 | name = "rand_distr"
1010 | version = "0.4.3"
1011 | source = "registry+https://github.com/rust-lang/crates.io-index"
1012 | checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
1013 | dependencies = [
1014 | "num-traits",
1015 | "rand",
1016 | ]
1017 |
1018 | [[package]]
1019 | name = "rawpointer"
1020 | version = "0.2.1"
1021 | source = "registry+https://github.com/rust-lang/crates.io-index"
1022 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
1023 |
1024 | [[package]]
1025 | name = "rayon"
1026 | version = "1.10.0"
1027 | source = "registry+https://github.com/rust-lang/crates.io-index"
1028 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
1029 | dependencies = [
1030 | "either",
1031 | "rayon-core",
1032 | ]
1033 |
1034 | [[package]]
1035 | name = "rayon-core"
1036 | version = "1.12.1"
1037 | source = "registry+https://github.com/rust-lang/crates.io-index"
1038 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
1039 | dependencies = [
1040 | "crossbeam-deque",
1041 | "crossbeam-utils",
1042 | ]
1043 |
1044 | [[package]]
1045 | name = "redox_syscall"
1046 | version = "0.5.3"
1047 | source = "registry+https://github.com/rust-lang/crates.io-index"
1048 | checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
1049 | dependencies = [
1050 | "bitflags",
1051 | ]
1052 |
1053 | [[package]]
1054 | name = "regex"
1055 | version = "1.10.6"
1056 | source = "registry+https://github.com/rust-lang/crates.io-index"
1057 | checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
1058 | dependencies = [
1059 | "aho-corasick",
1060 | "memchr",
1061 | "regex-automata",
1062 | "regex-syntax",
1063 | ]
1064 |
1065 | [[package]]
1066 | name = "regex-automata"
1067 | version = "0.4.7"
1068 | source = "registry+https://github.com/rust-lang/crates.io-index"
1069 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
1070 | dependencies = [
1071 | "aho-corasick",
1072 | "memchr",
1073 | "regex-syntax",
1074 | ]
1075 |
1076 | [[package]]
1077 | name = "regex-syntax"
1078 | version = "0.8.4"
1079 | source = "registry+https://github.com/rust-lang/crates.io-index"
1080 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
1081 |
1082 | [[package]]
1083 | name = "rustfft"
1084 | version = "6.2.0"
1085 | source = "registry+https://github.com/rust-lang/crates.io-index"
1086 | checksum = "43806561bc506d0c5d160643ad742e3161049ac01027b5e6d7524091fd401d86"
1087 | dependencies = [
1088 | "num-complex",
1089 | "num-integer",
1090 | "num-traits",
1091 | "primal-check",
1092 | "strength_reduce",
1093 | "transpose",
1094 | "version_check",
1095 | ]
1096 |
1097 | [[package]]
1098 | name = "rustix"
1099 | version = "0.38.34"
1100 | source = "registry+https://github.com/rust-lang/crates.io-index"
1101 | checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
1102 | dependencies = [
1103 | "bitflags",
1104 | "errno",
1105 | "libc",
1106 | "linux-raw-sys",
1107 | "windows-sys 0.52.0",
1108 | ]
1109 |
1110 | [[package]]
1111 | name = "rustversion"
1112 | version = "1.0.17"
1113 | source = "registry+https://github.com/rust-lang/crates.io-index"
1114 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
1115 |
1116 | [[package]]
1117 | name = "same-file"
1118 | version = "1.0.6"
1119 | source = "registry+https://github.com/rust-lang/crates.io-index"
1120 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
1121 | dependencies = [
1122 | "winapi-util",
1123 | ]
1124 |
1125 | [[package]]
1126 | name = "scan_fmt"
1127 | version = "0.2.6"
1128 | source = "registry+https://github.com/rust-lang/crates.io-index"
1129 | checksum = "0b53b0a5db882a8e2fdaae0a43f7b39e7e9082389e978398bdf223a55b581248"
1130 | dependencies = [
1131 | "regex",
1132 | ]
1133 |
1134 | [[package]]
1135 | name = "serde"
1136 | version = "1.0.209"
1137 | source = "registry+https://github.com/rust-lang/crates.io-index"
1138 | checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09"
1139 | dependencies = [
1140 | "serde_derive",
1141 | ]
1142 |
1143 | [[package]]
1144 | name = "serde_bytes"
1145 | version = "0.11.15"
1146 | source = "registry+https://github.com/rust-lang/crates.io-index"
1147 | checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a"
1148 | dependencies = [
1149 | "serde",
1150 | ]
1151 |
1152 | [[package]]
1153 | name = "serde_derive"
1154 | version = "1.0.209"
1155 | source = "registry+https://github.com/rust-lang/crates.io-index"
1156 | checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170"
1157 | dependencies = [
1158 | "proc-macro2",
1159 | "quote",
1160 | "syn 2.0.76",
1161 | ]
1162 |
1163 | [[package]]
1164 | name = "serde_tokenstream"
1165 | version = "0.1.7"
1166 | source = "registry+https://github.com/rust-lang/crates.io-index"
1167 | checksum = "797ba1d80299b264f3aac68ab5d12e5825a561749db4df7cd7c8083900c5d4e9"
1168 | dependencies = [
1169 | "proc-macro2",
1170 | "serde",
1171 | "syn 1.0.109",
1172 | ]
1173 |
1174 | [[package]]
1175 | name = "serde_tokenstream"
1176 | version = "0.2.2"
1177 | source = "registry+https://github.com/rust-lang/crates.io-index"
1178 | checksum = "64060d864397305347a78851c51588fd283767e7e7589829e8121d65512340f1"
1179 | dependencies = [
1180 | "proc-macro2",
1181 | "quote",
1182 | "serde",
1183 | "syn 2.0.76",
1184 | ]
1185 |
1186 | [[package]]
1187 | name = "sha2"
1188 | version = "0.10.8"
1189 | source = "registry+https://github.com/rust-lang/crates.io-index"
1190 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
1191 | dependencies = [
1192 | "cfg-if",
1193 | "cpufeatures",
1194 | "digest",
1195 | ]
1196 |
1197 | [[package]]
1198 | name = "shlex"
1199 | version = "1.3.0"
1200 | source = "registry+https://github.com/rust-lang/crates.io-index"
1201 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1202 |
1203 | [[package]]
1204 | name = "slab"
1205 | version = "0.4.9"
1206 | source = "registry+https://github.com/rust-lang/crates.io-index"
1207 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
1208 | dependencies = [
1209 | "autocfg",
1210 | ]
1211 |
1212 | [[package]]
1213 | name = "slotmap"
1214 | version = "1.0.7"
1215 | source = "registry+https://github.com/rust-lang/crates.io-index"
1216 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
1217 | dependencies = [
1218 | "version_check",
1219 | ]
1220 |
1221 | [[package]]
1222 | name = "smallvec"
1223 | version = "1.13.2"
1224 | source = "registry+https://github.com/rust-lang/crates.io-index"
1225 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
1226 |
1227 | [[package]]
1228 | name = "stacker"
1229 | version = "0.1.16"
1230 | source = "registry+https://github.com/rust-lang/crates.io-index"
1231 | checksum = "95a5daa25ea337c85ed954c0496e3bdd2c7308cc3b24cf7b50d04876654c579f"
1232 | dependencies = [
1233 | "cc",
1234 | "cfg-if",
1235 | "libc",
1236 | "psm",
1237 | "windows-sys 0.36.1",
1238 | ]
1239 |
1240 | [[package]]
1241 | name = "static_assertions"
1242 | version = "1.1.0"
1243 | source = "registry+https://github.com/rust-lang/crates.io-index"
1244 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
1245 |
1246 | [[package]]
1247 | name = "strength_reduce"
1248 | version = "0.2.4"
1249 | source = "registry+https://github.com/rust-lang/crates.io-index"
1250 | checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82"
1251 |
1252 | [[package]]
1253 | name = "string-interner"
1254 | version = "0.15.0"
1255 | source = "registry+https://github.com/rust-lang/crates.io-index"
1256 | checksum = "07f9fdfdd31a0ff38b59deb401be81b73913d76c9cc5b1aed4e1330a223420b9"
1257 | dependencies = [
1258 | "cfg-if",
1259 | "hashbrown",
1260 | "serde",
1261 | ]
1262 |
1263 | [[package]]
1264 | name = "syn"
1265 | version = "1.0.109"
1266 | source = "registry+https://github.com/rust-lang/crates.io-index"
1267 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
1268 | dependencies = [
1269 | "proc-macro2",
1270 | "quote",
1271 | "unicode-ident",
1272 | ]
1273 |
1274 | [[package]]
1275 | name = "syn"
1276 | version = "2.0.76"
1277 | source = "registry+https://github.com/rust-lang/crates.io-index"
1278 | checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525"
1279 | dependencies = [
1280 | "proc-macro2",
1281 | "quote",
1282 | "unicode-ident",
1283 | ]
1284 |
1285 | [[package]]
1286 | name = "tar"
1287 | version = "0.4.41"
1288 | source = "registry+https://github.com/rust-lang/crates.io-index"
1289 | checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909"
1290 | dependencies = [
1291 | "filetime",
1292 | "libc",
1293 | "xattr",
1294 | ]
1295 |
1296 | [[package]]
1297 | name = "thiserror"
1298 | version = "1.0.63"
1299 | source = "registry+https://github.com/rust-lang/crates.io-index"
1300 | checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
1301 | dependencies = [
1302 | "thiserror-impl",
1303 | ]
1304 |
1305 | [[package]]
1306 | name = "thiserror-impl"
1307 | version = "1.0.63"
1308 | source = "registry+https://github.com/rust-lang/crates.io-index"
1309 | checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
1310 | dependencies = [
1311 | "proc-macro2",
1312 | "quote",
1313 | "syn 2.0.76",
1314 | ]
1315 |
1316 | [[package]]
1317 | name = "time"
1318 | version = "0.3.36"
1319 | source = "registry+https://github.com/rust-lang/crates.io-index"
1320 | checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
1321 | dependencies = [
1322 | "deranged",
1323 | "itoa",
1324 | "num-conv",
1325 | "powerfmt",
1326 | "serde",
1327 | "time-core",
1328 | "time-macros",
1329 | ]
1330 |
1331 | [[package]]
1332 | name = "time-core"
1333 | version = "0.1.2"
1334 | source = "registry+https://github.com/rust-lang/crates.io-index"
1335 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
1336 |
1337 | [[package]]
1338 | name = "time-macros"
1339 | version = "0.2.18"
1340 | source = "registry+https://github.com/rust-lang/crates.io-index"
1341 | checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
1342 | dependencies = [
1343 | "num-conv",
1344 | "time-core",
1345 | ]
1346 |
1347 | [[package]]
1348 | name = "tinyvec"
1349 | version = "1.8.0"
1350 | source = "registry+https://github.com/rust-lang/crates.io-index"
1351 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938"
1352 | dependencies = [
1353 | "tinyvec_macros",
1354 | ]
1355 |
1356 | [[package]]
1357 | name = "tinyvec_macros"
1358 | version = "0.1.1"
1359 | source = "registry+https://github.com/rust-lang/crates.io-index"
1360 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
1361 |
1362 | [[package]]
1363 | name = "tract-core"
1364 | version = "0.21.6-pre"
1365 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1366 | dependencies = [
1367 | "anyhow",
1368 | "bit-set",
1369 | "derive-new",
1370 | "downcast-rs",
1371 | "dyn-clone",
1372 | "lazy_static",
1373 | "log",
1374 | "maplit",
1375 | "ndarray",
1376 | "num-complex",
1377 | "num-integer",
1378 | "num-traits",
1379 | "paste",
1380 | "rustfft",
1381 | "smallvec",
1382 | "tract-data",
1383 | "tract-linalg",
1384 | ]
1385 |
1386 | [[package]]
1387 | name = "tract-data"
1388 | version = "0.21.6-pre"
1389 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1390 | dependencies = [
1391 | "anyhow",
1392 | "downcast-rs",
1393 | "dyn-hash",
1394 | "half",
1395 | "itertools 0.12.1",
1396 | "lazy_static",
1397 | "maplit",
1398 | "ndarray",
1399 | "nom",
1400 | "num-integer",
1401 | "num-traits",
1402 | "scan_fmt",
1403 | "smallvec",
1404 | "string-interner",
1405 | ]
1406 |
1407 | [[package]]
1408 | name = "tract-hir"
1409 | version = "0.21.6-pre"
1410 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1411 | dependencies = [
1412 | "derive-new",
1413 | "log",
1414 | "tract-core",
1415 | ]
1416 |
1417 | [[package]]
1418 | name = "tract-linalg"
1419 | version = "0.21.6-pre"
1420 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1421 | dependencies = [
1422 | "cc",
1423 | "derive-new",
1424 | "downcast-rs",
1425 | "dyn-clone",
1426 | "dyn-hash",
1427 | "half",
1428 | "lazy_static",
1429 | "liquid",
1430 | "liquid-core",
1431 | "log",
1432 | "num-traits",
1433 | "paste",
1434 | "rayon",
1435 | "scan_fmt",
1436 | "smallvec",
1437 | "time",
1438 | "tract-data",
1439 | "unicode-normalization",
1440 | "walkdir",
1441 | ]
1442 |
1443 | [[package]]
1444 | name = "tract-nnef"
1445 | version = "0.21.6-pre"
1446 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1447 | dependencies = [
1448 | "byteorder",
1449 | "flate2",
1450 | "log",
1451 | "nom",
1452 | "tar",
1453 | "tract-core",
1454 | "walkdir",
1455 | ]
1456 |
1457 | [[package]]
1458 | name = "tract-onnx"
1459 | version = "0.21.6-pre"
1460 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1461 | dependencies = [
1462 | "bytes",
1463 | "derive-new",
1464 | "log",
1465 | "memmap2",
1466 | "num-integer",
1467 | "prost",
1468 | "smallvec",
1469 | "tract-hir",
1470 | "tract-nnef",
1471 | "tract-onnx-opl",
1472 | ]
1473 |
1474 | [[package]]
1475 | name = "tract-onnx-opl"
1476 | version = "0.21.6-pre"
1477 | source = "git+https://github.com/sonos/tract?rev=2a2914ac29390cc08963301c9f3d437b52dd321a#2a2914ac29390cc08963301c9f3d437b52dd321a"
1478 | dependencies = [
1479 | "getrandom",
1480 | "log",
1481 | "rand",
1482 | "rand_distr",
1483 | "rustfft",
1484 | "tract-nnef",
1485 | ]
1486 |
1487 | [[package]]
1488 | name = "transpose"
1489 | version = "0.2.3"
1490 | source = "registry+https://github.com/rust-lang/crates.io-index"
1491 | checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e"
1492 | dependencies = [
1493 | "num-integer",
1494 | "strength_reduce",
1495 | ]
1496 |
1497 | [[package]]
1498 | name = "typed-arena"
1499 | version = "2.0.2"
1500 | source = "registry+https://github.com/rust-lang/crates.io-index"
1501 | checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
1502 |
1503 | [[package]]
1504 | name = "typenum"
1505 | version = "1.17.0"
1506 | source = "registry+https://github.com/rust-lang/crates.io-index"
1507 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
1508 |
1509 | [[package]]
1510 | name = "ucd-trie"
1511 | version = "0.1.6"
1512 | source = "registry+https://github.com/rust-lang/crates.io-index"
1513 | checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9"
1514 |
1515 | [[package]]
1516 | name = "unicode-ident"
1517 | version = "1.0.12"
1518 | source = "registry+https://github.com/rust-lang/crates.io-index"
1519 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
1520 |
1521 | [[package]]
1522 | name = "unicode-normalization"
1523 | version = "0.1.23"
1524 | source = "registry+https://github.com/rust-lang/crates.io-index"
1525 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
1526 | dependencies = [
1527 | "tinyvec",
1528 | ]
1529 |
1530 | [[package]]
1531 | name = "unicode-segmentation"
1532 | version = "1.11.0"
1533 | source = "registry+https://github.com/rust-lang/crates.io-index"
1534 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
1535 |
1536 | [[package]]
1537 | name = "unicode-width"
1538 | version = "0.1.13"
1539 | source = "registry+https://github.com/rust-lang/crates.io-index"
1540 | checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
1541 |
1542 | [[package]]
1543 | name = "varion_backend"
1544 | version = "0.1.0"
1545 | dependencies = [
1546 | "bytes",
1547 | "candid",
1548 | "getrandom",
1549 | "ic-cdk 0.15.1",
1550 | "ic-cdk-macros 0.15.0",
1551 | "ic-cdk-timers",
1552 | "prost",
1553 | "serde",
1554 | "tract-onnx",
1555 | ]
1556 |
1557 | [[package]]
1558 | name = "version_check"
1559 | version = "0.9.5"
1560 | source = "registry+https://github.com/rust-lang/crates.io-index"
1561 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
1562 |
1563 | [[package]]
1564 | name = "walkdir"
1565 | version = "2.5.0"
1566 | source = "registry+https://github.com/rust-lang/crates.io-index"
1567 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
1568 | dependencies = [
1569 | "same-file",
1570 | "winapi-util",
1571 | ]
1572 |
1573 | [[package]]
1574 | name = "wasi"
1575 | version = "0.11.0+wasi-snapshot-preview1"
1576 | source = "registry+https://github.com/rust-lang/crates.io-index"
1577 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
1578 |
1579 | [[package]]
1580 | name = "winapi-util"
1581 | version = "0.1.9"
1582 | source = "registry+https://github.com/rust-lang/crates.io-index"
1583 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
1584 | dependencies = [
1585 | "windows-sys 0.59.0",
1586 | ]
1587 |
1588 | [[package]]
1589 | name = "windows-sys"
1590 | version = "0.36.1"
1591 | source = "registry+https://github.com/rust-lang/crates.io-index"
1592 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
1593 | dependencies = [
1594 | "windows_aarch64_msvc 0.36.1",
1595 | "windows_i686_gnu 0.36.1",
1596 | "windows_i686_msvc 0.36.1",
1597 | "windows_x86_64_gnu 0.36.1",
1598 | "windows_x86_64_msvc 0.36.1",
1599 | ]
1600 |
1601 | [[package]]
1602 | name = "windows-sys"
1603 | version = "0.52.0"
1604 | source = "registry+https://github.com/rust-lang/crates.io-index"
1605 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
1606 | dependencies = [
1607 | "windows-targets",
1608 | ]
1609 |
1610 | [[package]]
1611 | name = "windows-sys"
1612 | version = "0.59.0"
1613 | source = "registry+https://github.com/rust-lang/crates.io-index"
1614 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
1615 | dependencies = [
1616 | "windows-targets",
1617 | ]
1618 |
1619 | [[package]]
1620 | name = "windows-targets"
1621 | version = "0.52.6"
1622 | source = "registry+https://github.com/rust-lang/crates.io-index"
1623 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
1624 | dependencies = [
1625 | "windows_aarch64_gnullvm",
1626 | "windows_aarch64_msvc 0.52.6",
1627 | "windows_i686_gnu 0.52.6",
1628 | "windows_i686_gnullvm",
1629 | "windows_i686_msvc 0.52.6",
1630 | "windows_x86_64_gnu 0.52.6",
1631 | "windows_x86_64_gnullvm",
1632 | "windows_x86_64_msvc 0.52.6",
1633 | ]
1634 |
1635 | [[package]]
1636 | name = "windows_aarch64_gnullvm"
1637 | version = "0.52.6"
1638 | source = "registry+https://github.com/rust-lang/crates.io-index"
1639 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
1640 |
1641 | [[package]]
1642 | name = "windows_aarch64_msvc"
1643 | version = "0.36.1"
1644 | source = "registry+https://github.com/rust-lang/crates.io-index"
1645 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
1646 |
1647 | [[package]]
1648 | name = "windows_aarch64_msvc"
1649 | version = "0.52.6"
1650 | source = "registry+https://github.com/rust-lang/crates.io-index"
1651 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
1652 |
1653 | [[package]]
1654 | name = "windows_i686_gnu"
1655 | version = "0.36.1"
1656 | source = "registry+https://github.com/rust-lang/crates.io-index"
1657 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
1658 |
1659 | [[package]]
1660 | name = "windows_i686_gnu"
1661 | version = "0.52.6"
1662 | source = "registry+https://github.com/rust-lang/crates.io-index"
1663 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
1664 |
1665 | [[package]]
1666 | name = "windows_i686_gnullvm"
1667 | version = "0.52.6"
1668 | source = "registry+https://github.com/rust-lang/crates.io-index"
1669 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
1670 |
1671 | [[package]]
1672 | name = "windows_i686_msvc"
1673 | version = "0.36.1"
1674 | source = "registry+https://github.com/rust-lang/crates.io-index"
1675 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
1676 |
1677 | [[package]]
1678 | name = "windows_i686_msvc"
1679 | version = "0.52.6"
1680 | source = "registry+https://github.com/rust-lang/crates.io-index"
1681 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
1682 |
1683 | [[package]]
1684 | name = "windows_x86_64_gnu"
1685 | version = "0.36.1"
1686 | source = "registry+https://github.com/rust-lang/crates.io-index"
1687 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
1688 |
1689 | [[package]]
1690 | name = "windows_x86_64_gnu"
1691 | version = "0.52.6"
1692 | source = "registry+https://github.com/rust-lang/crates.io-index"
1693 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
1694 |
1695 | [[package]]
1696 | name = "windows_x86_64_gnullvm"
1697 | version = "0.52.6"
1698 | source = "registry+https://github.com/rust-lang/crates.io-index"
1699 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
1700 |
1701 | [[package]]
1702 | name = "windows_x86_64_msvc"
1703 | version = "0.36.1"
1704 | source = "registry+https://github.com/rust-lang/crates.io-index"
1705 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
1706 |
1707 | [[package]]
1708 | name = "windows_x86_64_msvc"
1709 | version = "0.52.6"
1710 | source = "registry+https://github.com/rust-lang/crates.io-index"
1711 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
1712 |
1713 | [[package]]
1714 | name = "xattr"
1715 | version = "1.3.1"
1716 | source = "registry+https://github.com/rust-lang/crates.io-index"
1717 | checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f"
1718 | dependencies = [
1719 | "libc",
1720 | "linux-raw-sys",
1721 | "rustix",
1722 | ]
1723 |
1724 | [[package]]
1725 | name = "zerocopy"
1726 | version = "0.7.35"
1727 | source = "registry+https://github.com/rust-lang/crates.io-index"
1728 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
1729 | dependencies = [
1730 | "byteorder",
1731 | "zerocopy-derive",
1732 | ]
1733 |
1734 | [[package]]
1735 | name = "zerocopy-derive"
1736 | version = "0.7.35"
1737 | source = "registry+https://github.com/rust-lang/crates.io-index"
1738 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
1739 | dependencies = [
1740 | "proc-macro2",
1741 | "quote",
1742 | "syn 2.0.76",
1743 | ]
1744 |
--------------------------------------------------------------------------------