merge PR #26 into master

pull/26/head
Niko PLP 6 months ago
commit ace0a30a91
  1. 18
      Cargo.lock
  2. 1
      ng-app/src-tauri/Cargo.toml
  3. 23
      ng-app/src-tauri/src/lib.rs
  4. 8
      ng-app/src/App.svelte
  5. 13
      ng-app/src/api.ts
  6. 0
      ng-app/src/apps/JsonLdEditor.svelte
  7. 873
      ng-app/src/classes.ts
  8. 86
      ng-app/src/lib/CenteredLayout.svelte
  9. 187
      ng-app/src/lib/DataClassIcon.svelte
  10. 28
      ng-app/src/lib/Install.svelte
  11. 2
      ng-app/src/lib/NoWallet.svelte
  12. 1
      ng-app/src/lib/Test.svelte
  13. 120
      ng-app/src/lib/ZeraIcon.svelte
  14. 8
      ng-app/src/routes/Install.svelte
  15. 2
      ng-app/src/routes/NURI.svelte
  16. 2
      ng-app/src/routes/NotFound.svelte
  17. 2
      ng-app/src/routes/UserRegistered.svelte
  18. 4
      ng-app/src/routes/WalletLogin.svelte
  19. 120
      ng-app/src/store.ts
  20. 629
      ng-app/src/zeras.ts
  21. 4
      ng-net/src/app_protocol.rs
  22. 4
      ng-oxigraph/src/oxigraph/sparql/update.rs
  23. 5
      ng-repo/src/types.rs
  24. 28
      ng-repo/src/utils.rs
  25. 1
      ng-sdk-js/Cargo.toml
  26. 6
      ng-sdk-js/src/lib.rs
  27. 2
      ngaccount/web/src/routes/Create.svelte
  28. 2
      ngaccount/web/src/routes/Delete.svelte
  29. 2
      ngone/web/src/routes/Install.svelte

18
Cargo.lock generated

@ -3290,6 +3290,7 @@ dependencies = [
"serde", "serde",
"serde_bytes", "serde_bytes",
"serde_json", "serde_json",
"sys-locale",
"tauri", "tauri",
"tauri-build", "tauri-build",
"tauri-plugin-window", "tauri-plugin-window",
@ -3408,7 +3409,7 @@ dependencies = [
"serde", "serde",
"sha1", "sha1",
"sha2 0.10.8", "sha2 0.10.8",
"siphasher 0.3.10", "siphasher 1.0.1",
"thiserror", "thiserror",
"zstd", "zstd",
] ]
@ -3449,7 +3450,7 @@ dependencies = [
[[package]] [[package]]
name = "ng-rocksdb" name = "ng-rocksdb"
version = "0.21.0-ngpreview.4" version = "0.21.0-ngpreview.4"
source = "git+https://git.nextgraph.org/NextGraph/rust-rocksdb.git?branch=master#e566341c319eead6637b1aecce5e92136e946ae5" source = "git+https://git.nextgraph.org/NextGraph/rust-rocksdb.git?branch=master#f1ce2e345f3d729350a02bcffb47c526674edd85"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"bzip2-sys", "bzip2-sys",
@ -3482,6 +3483,7 @@ dependencies = [
"serde_bare", "serde_bare",
"serde_bytes", "serde_bytes",
"serde_json", "serde_json",
"sys-locale",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"wasm-bindgen-test", "wasm-bindgen-test",
@ -5352,6 +5354,18 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "sys-locale"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0"
dependencies = [
"js-sys",
"libc",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "system-configuration" name = "system-configuration"
version = "0.6.0" version = "0.6.0"

@ -28,6 +28,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
serde_bytes = "0.11.7" serde_bytes = "0.11.7"
async-std = { version = "1.12.0", features = ["attributes", "unstable"] } async-std = { version = "1.12.0", features = ["attributes", "unstable"] }
sys-locale = { version = "0.3.1" }
ng-async-tungstenite = { git = "https://git.nextgraph.org/NextGraph/async-tungstenite.git", branch = "nextgraph", features = ["async-std-runtime", "async-native-tls"] } ng-async-tungstenite = { git = "https://git.nextgraph.org/NextGraph/async-tungstenite.git", branch = "nextgraph", features = ["async-std-runtime", "async-native-tls"] }
tauri = { version = "2.0.0-alpha.14", features = [] } tauri = { version = "2.0.0-alpha.14", features = [] }
tauri-plugin-window = "2.0.0-alpha.1" tauri-plugin-window = "2.0.0-alpha.1"

@ -13,6 +13,7 @@ use std::fs::write;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use sys_locale::get_locales;
use tauri::scope::ipc::RemoteDomainAccessScope; use tauri::scope::ipc::RemoteDomainAccessScope;
use tauri::utils::config::WindowConfig; use tauri::utils::config::WindowConfig;
use tauri::{path::BaseDirectory, App, Manager}; use tauri::{path::BaseDirectory, App, Manager};
@ -38,6 +39,27 @@ pub use mobile::*;
pub type SetupHook = Box<dyn FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send>; pub type SetupHook = Box<dyn FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send>;
#[tauri::command(rename_all = "snake_case")]
async fn locales() -> Result<Vec<String>, ()> {
Ok(get_locales()
.filter_map(|lang| {
if lang == "C" || lang == "c" {
None
} else {
let mut split = lang.split('.');
let code = split.next().unwrap();
let code = code.replace("_", "-");
let mut split = code.rsplitn(2, '-');
let country = split.next().unwrap();
Some(match split.next() {
Some(next) => format!("{}-{}", next, country.to_uppercase()),
None => country.to_string(),
})
}
})
.collect())
}
#[tauri::command(rename_all = "snake_case")] #[tauri::command(rename_all = "snake_case")]
async fn test(app: tauri::AppHandle) -> Result<(), ()> { async fn test(app: tauri::AppHandle) -> Result<(), ()> {
let path = app let path = app
@ -514,6 +536,7 @@ impl AppBuilder {
.plugin(tauri_plugin_window::init()) .plugin(tauri_plugin_window::init())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
test, test,
locales,
wallet_gen_shuffle_for_pazzle_opening, wallet_gen_shuffle_for_pazzle_opening,
wallet_gen_shuffle_for_pin, wallet_gen_shuffle_for_pin,
wallet_open_with_pazzle, wallet_open_with_pazzle,

@ -19,19 +19,20 @@
active_session, active_session,
close_active_session, close_active_session,
disconnections_subscribe, disconnections_subscribe,
select_default_lang,
} from "./store"; } from "./store";
import Home from "./routes/Home.svelte"; import Home from "./routes/Home.svelte";
import Test from "./routes/Test.svelte"; import Test from "./routes/Test.svelte";
import URI from "./routes/URI.svelte"; import NURI from "./routes/NURI.svelte";
import NotFound from "./routes/NotFound.svelte"; import NotFound from "./routes/NotFound.svelte";
import WalletCreate from "./routes/WalletCreate.svelte"; import WalletCreate from "./routes/WalletCreate.svelte";
import Invitation from "./routes/Invitation.svelte"; import Invitation from "./routes/Invitation.svelte";
import WalletLogin from "./routes/WalletLogin.svelte"; import WalletLogin from "./routes/WalletLogin.svelte";
import User from "./routes/User.svelte"; import User from "./routes/User.svelte";
import UserRegistered from "./routes/UserRegistered.svelte"; import UserRegistered from "./routes/UserRegistered.svelte";
import Install from "./lib/Install.svelte"; import Install from "./routes/Install.svelte";
import ng from "./api"; import ng from "./api";
@ -44,7 +45,7 @@
routes.set("/user", User); routes.set("/user", User);
routes.set("/user/registered", UserRegistered); routes.set("/user/registered", UserRegistered);
if (import.meta.env.NG_APP_WEB) routes.set("/install", Install); if (import.meta.env.NG_APP_WEB) routes.set("/install", Install);
routes.set(/^\/ng(.*)/i, URI); routes.set(/^\/did:ng(.*)/i, NURI);
routes.set("*", NotFound); routes.set("*", NotFound);
let unsubscribe = () => {}; let unsubscribe = () => {};
@ -59,6 +60,7 @@
onMount(async () => { onMount(async () => {
try { try {
await select_default_lang();
await disconnections_subscribe(); await disconnections_subscribe();
} catch (e) { } catch (e) {
//console.log("called disconnections_subscribe twice"); //console.log("called disconnections_subscribe twice");

@ -98,6 +98,19 @@ const handler = {
}; };
//console.log(info,res); //console.log(info,res);
return res; return res;
} else if (path[0] === "locales") {
let from_rust = await tauri.invoke("locales",{});
let from_js = window.navigator.languages;
console.log(from_rust,from_js);
for (let lang of from_js) {
let split = lang.split("-");
if (split[1]) {
lang = split[0] + "-" + split[1].toUpperCase();
}
if (!from_rust.includes(lang)) { from_rust.push(lang);}
}
return from_rust;
} else if (path[0] === "disconnections_subscribe") { } else if (path[0] === "disconnections_subscribe") {
let { getCurrent } = await import("@tauri-apps/plugin-window"); let { getCurrent } = await import("@tauri-apps/plugin-window");
let callback = args[0]; let callback = args[0];

@ -0,0 +1,873 @@
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
// "post/rich", "post/md", "post/text", "post/html", "post/asciidoc", "page", "code", "code/*", "app", "app/z", "class", "schema", "schema/owl|rdfs|shacl|shex", "service", "service/rust", "service/deno", "contract", "app/n:xxx.xx.xx:", "app/o:",
// "query/sparql", "query/graphql", "query/text", "query/web",
// "data/graph", "data/json", "data/array", "data/map", "data/xml", "data/table", "data/collection", "data/board", "data/grid", "data/geomap",
// "e/email", "e/web", "e/http://[url of class in ontology]", "e/rdf" (read-only cache of RDF fetched from web2.0)
// "mc/text", "mc/link", "mc/card", "mc/pad",
// "doc/diagram","doc/chart", "doc/pdf", "doc/odf", "doc/latex", "doc/ps", "doc/music", "doc/maths", "doc/chemistry", "doc/braille", "doc/ancientscript",
// "media/image", "media/reel", "media/album", "media/video", "media/audio", "media/song", "media/subtitle", "media/overlay",
// "social/channel", "social/stream", "social/contact", "social/event", "social/calendar", "social/scheduler", "social/reaction"
// "prod/task", "prod/project", "prod/issue", "prod/form", "prod/filling", "prod/cad", "prod/slides", "prod/question", "prod/answer", "prod/poll", "prod/vote"
// "file", "file/iana/*", "file/gimp", "file/inkscape", "file/kdenlive", "file/blender", "file/openscad", "file/lyx", "file/scribus", "file/libreoffice",
// application/vnd.api+json
// application/activity+json
// epub, dejavu,
// animation: snap, lottie, smil editor: https://github.com/HaikuTeam/animator/
export const official_classes = {
"post/rich": {
"ng:crdt": "YXml",
"ng:n": "Post - Rich Text", // editor: y-ProseMirror, viewer: https://www.npmjs.com/package/prosemirror-to-html-js or https://prosemirror.net/docs/ref/version/0.4.0.html#toDOM https://prosemirror.net/docs/ref/version/0.4.0.html#toHTML
"ng:a": "A Post with Rich Text, including images, links, formatted text, and embeds of other content",
"ng:o": "n:g:z:post:rich",
"ng:w": "n:g:z:post_rich_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Article"],
},
"post/md": {
"ng:crdt": "YXml",
"ng:n": "Post - MarkDown", // editor y-MilkDown, viewer: https://github.com/wooorm/markdown-rs
"ng:a": "A Post with MarkDown, including images, links, formatted text, and embeds of other content",
"ng:o": "n:g:z:post:md",
"ng:w": "n:g:z:post_md_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["file/iana/text/markdown", "code/markdown","as:Article"],
},
"post/text": {
"ng:crdt": "YText",
"ng:n": "Post - Plain Text",
"ng:a": "A Post with Plain Text",
"ng:o": "n:g:z:post:text",
"ng:w": "n:g:z:code_editor",
"ng:x": {
"as":true,
},
"ng:compat": ["file/iana/text/plain", "code/plaintext","as:Article"],
},
"post/html": {
"ng:crdt": "YXml",
"ng:n": "Post - TinyMCE",
"ng:x": {
"as":true,
},
"ng:a": "A Post based on TinyMCE, including images, links, formatted text, and embeds of other content",
"ng:compat": ["as:Article"],
},
"post/asciidoc": { // display with https://github.com/asciidoctor/asciidoctor.js/
"ng:crdt": "YText",
"ng:n": "Post - AsciiDoc",
"ng:a": "A Post based on AsciiDoc format",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Article"],
},
"page": {
"ng:crdt": "YXml",
"ng:n": "Page", // based on GrapeJS, VvvebJs, or Astro ?
"ng:a": "A Page and Site builder",
"ng:compat": [],
},
"code": {
"ng:crdt": "YText",
"ng:n": "Source Code", // edited with CodeMirror, displayed with highlight.js
"ng:a": "A Source Code file. many languages supported",
"ng:o": "n:g:z:pre",
"ng:w": "n:g:z:code_editor",
"ng:compat": ["code/*","file/iana/text/javascript","file/iana/text/css","file/iana/text/html","file/iana/text/markdown", "file/iana/application/xml", "file/iana/application/yaml", "file/iana/text/xml", "file/iana/application/xhtml+xml"],
},
"app": {
"ng:n": "Official App",
"ng:a": "App provided by NextGraph platform",
},
"app/z": {
"ng:crdt": "Elmer",
"ng:n": "Application", // Editor: Monaco
"ng:a": "Create an Application based on NextGraph Framework",
"ng:o": "n:g:z:app_store",
"ng:w": "n:g:z:app_editor",
"ng:include": ["schema/*","service/*","code","file"],
"ng:compat": ["code/svelte"],
},
"class": {
"ng:crdt": "Graph",
"ng:n": "Class",
"ng:a": "Define a custom Class for your data",
"ng:x": {
"rdfs":true,
},
"ng:compat": ["rdfs:Class"],
},
"schema/rdfs": {
"ng:crdt": "Graph",
"ng:n": "Schema - RDFS",
"ng:a": "Define the Schema, Ontology or Vocabulary for your data and the relations between them, with RDFS",
"ng:o": "n:g:z:json_ld_editor", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"rdfs":true,
},
"ng:include": ["data/graph"],
"ng:compat": ["rdfs:*","class"],
},
"schema/owl": { // display with https://github.com/VisualDataWeb/WebVOWL
"ng:crdt": "Graph",
"ng:n": "Schema - OWL",
"ng:a": "Define the Schema, Ontology or Vocabulary for your data and the relations between them, with OWL",
"ng:o": "n:g:z:owl_viewer", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"owl":true,
},
"ng:include": ["data/graph"],
"ng:compat": ["owl:Ontology"],
},
"schema/shacl": {
"ng:crdt": "Graph",
"ng:n": "Schema - SHACL",
"ng:a": "Define the Schema, Ontology or Vocabulary for your data and the relations between them, with SHACL",
"ng:o": "n:g:z:json_ld_editor", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"sh":true,
},
"ng:include": ["data/graph"],
"ng:compat": ["sh:Shape", "file/iana/text/shaclc" ],
},
"schema/shex": {
"ng:crdt": "Graph",
"ng:n": "Schema - SHEX",
"ng:a": "Define the Schema, Ontology or Vocabulary for your data and the relations between them, with SHEX",
"ng:o": "n:g:z:json_ld_editor", // default viewer
"ng:w": "n:g:z:ontology_editor", // default editor
"ng:x": {
"shex":true,
},
"ng:include": ["data/graph"],
"ng:compat": ["shex:*", "file/iana/text/shex", "code/shexc" ],
},
"service": {
"ng:n": "Internal Service",
"ng:a": "Service provided by NextGraph framework",
"ng:o": "n:g:z:service_invoke", // default viewer
},
"service/rust": {
"ng:crdt": "YText",
"ng:n": "Service - Rust", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Service written in Rust and compiled to WASM",
"ng:o": "external_service_invoke", // default viewer
"ng:w": "n:g:z:service_editor", // default editor
"ng:compat": ["code/rust", "file/iana/application/wasm"],
},
"service/deno": {
"ng:crdt": "YText",
"ng:n": "Service - Deno/JS", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Service written in JS/TS for Deno or NodeJS",
"ng:o": "external_service_invoke", // default viewer
"ng:w": "n:g:z:service_editor", // default editor
"ng:compat": ["code/javascript", "code/typescript", "file/iana/text/javascript", "file/iana/application/node"],
},
"contract": {
"ng:crdt": "YText",
"ng:n": "Contract", // edited with CodeMirror, displayed with highlight.js
"ng:a": "Smart Contract with Rust or JS code",
"ng:compat": ["code/rust", "file/iana/application/wasm", "code/javascript", "code/typescript", "file/iana/text/javascript", "file/iana/application/node"],
},
"query/sparql": {
"ng:crdt": "YText",// uses ng:default_graph and ng:named_graph predicates
"ng:n": "SPARQL Query", // edited with YASGUI or Sparnatural, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Query that can be invoked",
"ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_query:yasgui",
"ng:compat": ["code/sparql", "file/iana/application/sparql-query"],
},
"query/sparql_update": {
"ng:crdt": "YText",// uses ng:default_graph and ng:named_graph predicates
"ng:n": "SPARQL Update", // edited with YASGUI, displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:a": "Saved SPARQL Update that can be invoked",
"ng:o": "n:g:z:sparql:invoke",
"ng:w": "n:g:z:sparql_update:yasgui",
"ng:compat": ["code/sparql", "file/iana/application/sparql-update"],
},
"query/graphql": {
"ng:crdt": "YText", // uses ng:default_graph predicate
"ng:n": "GraphQL Query", // edited with https://github.com/graphql/graphiql or https://github.com/graphql-editor/graphql-editor, displayed with highlight.js
"ng:a": "Saved GraphQL Query that can be invoked",
"ng:o": "n:g:z:graphql:invoke",
"ng:w": "n:g:z:graphql_query",
"ng:compat": ["code/graphql", "file/iana/application/graphql+json"],
},
"query/text": {
"ng:crdt": "Graph",
"ng:n": "Text Search",
"ng:a": "Saved Text Search and its results",
"ng:compat": [],
},
"query/web": {
"ng:crdt": "Graph",
"ng:n": "Web Search",
"ng:a": "Saved Web Search and its results",
"ng:compat": [],
},
"data/graph": {
"ng:crdt": "Graph", // https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "Graph",
"ng:a": "Define the Graph of your data with Semantic Web / Linked Data",
"ng:o": "n:g:z:json_ld_editor", // default viewer
"ng:w": "n:g:z:json_ld_editor", // default editor
"ng:x": {
"rdf":true,
"xsd":true,
},
"ng:compat": [ "rdf:*", "xsd:*", "file/iana/text/n3", "file/iana/text/rdf+n3", "file/iana/text/turtle", "file/iana/application/n-quads", "file/iana/application/trig", "file/iana/application/n-triples", "file/iana/application/rdf+xml", "file/iana/application/ld+json"],
},
"data/json": {
"ng:crdt": "Automerge",
"ng:n": "JSON",
"ng:a": "JSON Data CRDT",
"ng:o": "n:g:z:json_editor", // default viewer
"ng:w": "n:g:z:json_editor", // default editor
"ng:compat": ["file/iana/application/json", "code:json"],
},
"data/array": {
"ng:crdt": "YArray",
"ng:n": "JSON Array",
"ng:a": "JSON Array CRDT",
"ng:o": "n:g:z:json_editor", // default viewer
"ng:w": "n:g:z:json_editor", // default editor
"ng:compat": ["file/iana/application/json", "code:json"],
},
"data/map": {
"ng:crdt": "YMap",
"ng:n": "JSON Map",
"ng:a": "JSON Map CRDT",
"ng:o": "n:g:z:json_editor", // default viewer
"ng:w": "n:g:z:json_editor", // default editor
"ng:compat": ["file/iana/application/json", "code:json"],
},
"data/xml": {
"ng:crdt": "YXml",
"ng:n": "XML",
"ng:a": "XML Data CRDT",
"ng:compat": ["file/iana/text/xml","file/iana/application/xml", "code:xml"],
},
"data/table": {
"ng:crdt": "Automerge", // see https://github.com/frappe/datatable
"ng:n": "Table", // see https://specs.frictionlessdata.io/table-schema displayed with pivot table see https://activetable.io/docs/data https://www.npmjs.com/package/pivottable https://socket.dev/npm/package/svelte-pivottable/alerts/0.2.0?tab=dependencies
"ng:a": "Data in a Table (columns and rows)",
"ng:o": "n:g:z:pivot",
"ng:compat": ["file/iana/application/sparql-results+json","file/iana/application/sparql-results+xml","file/iana/text/csv"],
},
"data/collection": {
"ng:crdt": "Graph",
"ng:n": "Collection",
"ng:a": "An ordered list of items",
"ng:o": "n:g:z:list",
"ng:x": {
"as": true,
"rdf": true,
},
"ng:compat": ["as:Collection","rdf:List","rdf:Seq"],
},
"data/container": {
"ng:crdt": "Graph",
"ng:n": "Container",
"ng:a": "An unordered list of items",
"ng:o": "n:g:z:list",
"ng:x": {
"rdf": true,
"rdfs": true,
"ldp": true,
},
"ng:compat": ["rdfs:member","ldp:contains","rdf:Bag","rdf:Alt"],
},
"data/board": {
"ng:crdt": "Graph",
"ng:n": "Board",
"ng:a": "Whiteboard, infinite canvas to arrange your content in 2D",
"ng:o": "n:g:z:board",
"ng:include": [],
"ng:compat": [], //https://jsoncanvas.org/ https://www.canvasprotocol.org/ https://github.com/orgs/ocwg/discussions/25 https://infinitecanvas.tools/gallery/
},
"data/grid": {
"ng:crdt": "Graph",
"ng:n": "Grid",
"ng:a": "Grid representation of a collection or container",
"ng:o": "n:g:z:grid",
"ng:include": ["data/container","data/collection","data/table","media/album"],
"ng:compat": [],
},
"data/geomap": { // https://github.com/leaflet/leaflet
"ng:crdt": "Graph",
"ng:n": "Geo Map",
"ng:a": "Geographical Map",
"ng:x": {
"wgs": true,
"gn": true,
"as": true,
},
"ng:compat": ["as:Place","wgs:*","gn:*", "file/iana/application/geo+json", "file/iana/application/vnd.mapbox-vector-tile"], // see also https://github.com/topojson/topojson
},
"e/email": {
"ng:crdt": "Graph",
"ng:n": "Email",
"ng:a": "Email content and headers",
"ng:x": {
"email": "http://www.invincea.com/ontologies/icas/1.0/email#" //https://raw.githubusercontent.com/twosixlabs/icas-ontology/master/ontology/email.ttl
},
"ng:compat": ["file/iana/message/rfc822","file/iana/multipart/related"],
},
"e/web": {
"ng:crdt": "Graph",
//https://www.npmjs.com/package/warcio https://github.com/N0taN3rd/node-warc
"ng:n": "Web Archive",
"ng:a": "Archive the content of a web page",
"ng:compat": ["file/iana/application/warc","file/iana/multipart/related"],
},
"e/rdf": {
"ng:crdt": "Graph",
"ng:n": "RDF Archive",
"ng:a": "Archive the triples of an RDF resource dereferenced with HTTP",
"ng:include": ["data/graph"],
},
"mc/text": {
"ng:crdt": "Graph",
"ng:n": "Text Selection",
"ng:a": "Text Selection copied into Magic Carpet",
},
"mc/link": {
"ng:crdt": "Graph",
"ng:n": "Link",
"ng:a": "Link to a document kept in Magic Carpet",
},
"plato/card": {
"ng:crdt": "Graph",
"ng:n": "Card",
"ng:a": "Card representation of a document",
"ng:o": "n:g:z:card",
},
"plato/pad": {
"ng:crdt": "Graph",
"ng:n": "Pad",
"ng:a": "Pad representation of a document",
"ng:o": "n:g:z:pad",
},
"doc/diagram/mermaid" : {
"ng:crdt": "YText",
"ng:n": "Diagram - Mermaid",
"ng:a": "Describe Diagrams with Mermaid",
"ng:compat": ["file/iana/application/vnd.mermaid"]
},
"doc/diagram/drawio" : {
"ng:crdt": "YXml",
"ng:n": "Diagram - DrawIo",
"ng:a": "Draw Diagrams with DrawIo",
"ng:compat": ["file/iana/application/vnd.jgraph.mxfile","file/iana/application/x-drawio"]
},
"doc/diagram/graphviz" : {
"ng:crdt": "YText",
"ng:n": "Diagram - Graphviz",
"ng:a": "Describe Diagrams with Graphviz",
"ng:compat": ["file/iana/text/vnd.graphviz"]
},
"doc/diagram/excalidraw" : {
"ng:crdt": "Automerge",
"ng:n": "Diagram - Excalidraw",
"ng:a": "Collaborate on Diagrams with Excalidraw",
"ng:compat": ["file/iana/application/vnd.excalidraw+json"]
},
"doc/diagram/gantt" : { //https://github.com/frappe/gantt
"ng:crdt": "Automerge",
"ng:n": "Diagram - Gantt",
"ng:a": "Interactive gantt chart",
"ng:compat": []
},
"doc/diagram/flowchart" : { //https://github.com/adrai/flowchart.js
"ng:crdt": "YText",
"ng:n": "Diagram - Flowchart",
"ng:a": "flow chart diagrams",
"ng:compat": []
},
"doc/diagram/sequence" : { //https://github.com/bramp/js-sequence-diagrams
"ng:crdt": "YText",
"ng:n": "Diagram - Sequence",
"ng:a": "sequence diagrams",
"ng:compat": []
},
// checkout https://www.mindmaps.app/ but it is AGPL
"doc/diagram/markmap" : { //https://github.com/markmap/markmap
"ng:crdt": "YText",
"ng:n": "Diagram - Markmap",
"ng:a": "mindmaps with markmap",
"ng:compat": []
},
"doc/diagram/mymind" : { //https://github.com/markmap/markmap
"ng:crdt": "YText", // see MyMind format, MindMup JSON, FreeMind XML and MindMap Architect XML
"ng:n": "Diagram - Mymind",
"ng:a": "mindmaps with mymind",
"ng:compat": [] // https://github.com/ondras/my-mind/wiki/Saving-and-loading#file-formats
},
"doc/diagram/jsmind" : { //https://github.com/hizzgdev/jsmind
"ng:crdt": "Automerge",
"ng:n": "Diagram - jsmind",
"ng:a": "mindmaps with jsmind",
"ng:compat": [] // https://hizzgdev.github.io/jsmind/docs/en/1.usage.html
},
// DC and C3 have Crossfilter https://github.com/dc-js/dc.js http://crossfilter.github.io/crossfilter/ https://github.com/c3js/c3 http://dc-js.github.io/dc.js/
// take inspiration from https://github.com/metabase/metabase
// have a look at https://github.com/observablehq
// another open source dashboard with many data sources https://github.com/getredash/redash
// and another one https://github.com/apache/superset
// https://github.com/Rich-Harris/pancake
// https://github.com/williamngan/pts
// https://visjs.org/
"doc/viz/cytoscape" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Cytoscape",
"ng:a": "Graph theory (network) visualization",
"ng:compat": [] // https://github.com/cytoscape/cytoscape.js
},
"doc/viz/vega" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Vega",
"ng:a": "Grammar for interactive graphics",
"ng:compat": [] // https://vega.github.io/vega-lite/docs/ https://github.com/vega/editor
},
"doc/viz/vizzu" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Vizzu",
"ng:a": "Animated data visualizations and data stories",
"ng:compat": [] // https://github.com/vizzuhq/vizzu-lib
},
"doc/viz/plotly" : { //https://github.com/plotly/plotly.js
"ng:crdt": "Automerge",
"ng:n": "Viz - Plotly",
"ng:a": "Declarative charts",
"ng:compat": [] // https://github.com/cytoscape/cytoscape.js
},
"doc/viz/avail" : {
"ng:crdt": "Automerge",
"ng:n": "Viz - Avail",
"ng:a": "Time Data Availability Visualization",
"ng:compat": [] // https://github.com/flrs/visavail
},
"doc/chart/frappecharts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Frappe",
"ng:a": "GitHub-inspired responsive charts",
"ng:compat": [] // https://github.com/frappe/charts
},
"doc/chart/financial" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Financial",
"ng:a": "Financial charts",
"ng:compat": [] //https://github.com/tradingview/lightweight-charts
},
// have a look at https://github.com/cube-js/cube and https://awesome.cube.dev/ and https://frappe.io/products
"doc/chart/apexcharts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - ApexCharts",
"ng:a": "Interactive data visualizations",
"ng:compat": [] // https://github.com/apexcharts/apexcharts.js
},
//realtime data with https://github.com/square/cubism
"doc/chart/billboard" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - BillBoard",
"ng:a": "Interactive data visualizations based on D3",
"ng:compat": [] // https://github.com/naver/billboard.js
},
"doc/chart/echarts" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - ECharts",
"ng:a": "Interactive charting and data visualization with Apache ECharts",
"ng:compat": [] // https://github.com/apache/echarts
},
"doc/chart/chartjs" : {
"ng:crdt": "Automerge",
"ng:n": "Charts - Chart.js",
"ng:a": "Simple yet flexible charting for designers & developers with Chart.js",
"ng:compat": [] // https://github.com/chartjs/Chart.js
},
// see if to provide plain D3, and also all the https://github.com/antvis libraries: G2, G6, L7, S2, X6. Have a look at AVA
"doc/pdf": {
"ng:crdt": "Graph",
"ng:n": "PDF",
"ng:a": "upload and display a PDF file",
"ng:compat": ["file/iana/application/pdf"] // https://github.com/mozilla/pdf.js https://viewerjs.org/
},
"doc/odf": { //!!! becareful: AGPL
"ng:crdt": "Graph",
"ng:n": "OpenDocumentFormat (ODF)",
"ng:a": "upload and display an ODF file",
"ng:compat": ["file/iana/application/vnd.oasis.opendocument*"] // https://webodf.org/ https://github.com/webodf/WebODF https://viewerjs.org/
},
// see also https://github.com/Mathpix/mathpix-markdown-it
"doc/latex": {
"ng:crdt": "Graph",
"ng:n": "Latex",
"ng:a": "upload and display a Latex or Tex file",
"ng:compat": ["file/iana/application/x-tex","file/iana/text/x-tex"] // https://github.com/michael-brade/LaTeX.js https://github.com/mathjax/MathJax
},
"doc/ps": { //!!! becareful: AGPL https://github.com/ochachacha/ps-wasm
"ng:crdt": "Graph",
"ng:n": "Postscript",
"ng:a": "upload and display a PostScript file",
"ng:compat": ["file/iana/application/postscript"] // https://www.npmjs.com/package/ghostscript4js
},
"doc/music/abc": { //https://github.com/paulrosen/abcjs
"ng:crdt": "YText",
"ng:n": "Music ABC",
"ng:a": "sheet music notation",
"ng:compat": []
},
"doc/music/guitar": { //https://github.com/birdca/fretboard
"ng:crdt": "YText",
"ng:n": "Music - Guitar",
"ng:a": "charts for guitar chords and scales",
"ng:compat": []
},
"doc/maths": { //https://github.com/KaTeX/KaTeX
"ng:crdt": "YText",
"ng:n": "Maths",
"ng:a": "TeX math rendering",
"ng:compat": ["file/iana/application/x-tex","file/iana/text/x-tex"]
},
"doc/chemistry": { //GPL!! https://github.com/aeris-data/ChemDoodle/tree/master/ChemDoodleWeb-8.0.0 or https://github.com/aseevia/smiles-3d-vue
"ng:crdt": "YText",
"ng:n": "Chemical",
"ng:a": "simplified molecular-input line-entry system (SMILES)",
"ng:compat": ["file/iana/chemical/x-daylight-smiles"] // https://en.wikipedia.org/wiki/SYBYL_line_notation and http://fileformats.archiveteam.org/wiki/Chemical_data
},
"doc/ancientscript": { //https://dn-works.com/ufas/
"ng:crdt": "YText", // use Unicode and special fonts
"ng:n": "Ancient Script",
"ng:a": "Ancient Script",
"ng:compat": []
},
"doc/braille": { //https://en.wikipedia.org/wiki/Braille_Patterns
"ng:crdt": "YText", // use Unicode and special fonts
"ng:n": "Braille Patterns",
"ng:a": "Braille Patterns",
"ng:compat": []
},
"media/image": {
"ng:crdt": "Graph",
"ng:n": "Image",
"ng:a": "upload and display an image",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file/iana/image*","as:Image"]
},
"media/reel": {
"ng:crdt": "Graph",
"ng:n": "Reel",
"ng:a": "upload and display a Reel (video from mobile)",
"ng:o": "n:g:z:media",
"ng:compat": ["file/iana/video*"]
},
"media/video": {
"ng:crdt": "Graph",
"ng:n": "Video",
"ng:a": "upload and display a Video (and film)",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file/iana/video*","as:Video"]
},
"media/album": {
"ng:crdt": "Graph",
"ng:n": "Album",
"ng:a": "Assemble several images and/or videos into an ordered Album",
"ng:o": "n:g:z:gallery",
"ng:include": ["data/collection"],
"ng:compat": []
},
"media/audio": {
"ng:crdt": "Graph",
"ng:n": "Audio",
"ng:a": "upload and play an Audio file, Audio note or Voice message",
"ng:o": "n:g:z:media",
"ng:x": {
"as":true,
},
"ng:compat": ["file/iana/audio*","as:Audio"]
},
"media/song": {
"ng:crdt": "Graph",
"ng:n": "Song",
"ng:a": "A song from an artist,album and/or lyrics",
"ng:o": "n:g:z:media",
"ng:x": {
"music": "http://purl.org/ontology/mo/",
},
"ng:compat": ["music:MusicalWork","music:MusicArtist", "music:Lyrics"]
// see also https://polifonia-project.eu/wp-content/uploads/2022/01/Polifonia_D2.1_V1.0.pdf
// Music ontology http://musicontology.com/docs/faq.html with data based on existing databases https://musicbrainz.org/doc/MusicBrainz_Database/Schema https://github.com/megaconfidence/open-song-database https://www.discogs.com/developers
},
"media/subtitle": { //https://captioneasy.com/subtitle-file-formats/
"ng:crdt": "YText",
"ng:n": "Subtitles",
"ng:a": "Subtitles",
"ng:compat": [] // TBD
},
"media/overlay": {
"ng:crdt": "Graph",
"ng:n": "Overlay",
"ng:a": "Composition of an image, reel, text, icon, link, mention or other content into a layered content",
"ng:o": "n:g:z:media",
"ng:compat": []
},
"social/channel": {
"ng:crdt": "Graph",
"ng:n": "Channel",
"ng:a": "Broadcast channel with subscribers",
"ng:compat": []
},
"social/stream": {
"ng:crdt": "Graph",
"ng:n": "Stream",
"ng:a": "A document or store's stream branch",
"ng:compat": []
},
"social/contact": {
"ng:crdt": "Graph",
"ng:n": "Contact",
"ng:a": "Contact: an Individual, Organization or Group",
"ng:x": {
"vcard":true,
"foaf": true,
},
"ng:include": ["data/graph"],
"ng:compat": ["foaf:Person","foaf:Agent","vcard:Individual", "vcard:Organization", "vcard:Group", "file/iana/text/vcard", "file/iana/application/vcard+json", "file/iana/application/vcard+xml" ],
},
"social/event": {
"ng:crdt": "Graph",
"ng:n": "Event",
"ng:a": "An event occuring in specific location and time",
"ng:x": {
"as":true,
},
"ng:include": ["post/*"],
"ng:compat": ["as:Event"]
},
"social/calendar": {
"ng:crdt": "Graph",
"ng:n": "Calendar",
"ng:a": "A calendar where events are gathered",
"ng:x": {
"as":true,
"time": true,
},
"ng:include": ["data/collection"],
"ng:compat": ["time:TemporalEntity", "file/iana/text/calendar", "file/iana/application/calendar+xml", "file/iana/application/calendar+json"] //https://www.rfc-editor.org/rfc/rfc5545
},
"social/scheduler": {
"ng:crdt": "Graph",
"ng:n": "Scheduler",
"ng:a": "Helps finding a common time slot for several participants to a future event",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Invite","as:Reject","as:Accept","as:TentativeAccept","as:TentativeReject"]
},
"social/reaction": {
"ng:crdt": "Graph",
"ng:n": "Reaction",
"ng:a": "A reaction by user to some content",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Like", "as:Dislike", "as:Listen", "as:Read", "as:View"]
},
"prod/task": {
"ng:crdt": "Graph",
"ng:n": "Task",
"ng:a": "A task to be done",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["post/*"],
"ng:compat": ["pair:Task"] //see VTODO in iCalendar https://www.cs.utexas.edu/~mfkb/RKF/tree/components/specs/ontologies/Calendar-onto.html
// see todo and todoList of Mobilizon https://framagit.org/framasoft/mobilizon/-/blob/main/lib/federation/activity_stream/converter/todo.ex
// https://framagit.org/framasoft/mobilizon/-/blob/main/lib/federation/activity_stream/converter/todo_list.ex
},
"prod/project": {
"ng:crdt": "Graph",
"ng:n": "Project",
"ng:a": "A project management / KanBan",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["post/*"],
"ng:compat": ["pair:Project"]
},
// see SRO https://www.researchgate.net/publication/350158531_From_a_Scrum_Reference_Ontology_to_the_Integration_of_Applications_for_Data-Driven_Software_Development
// https://ceur-ws.org/Vol-1442/paper_4.pdf
// see focalbaord, specially for their import scripts https://github.com/mattermost/focalboard/tree/main/import
// and their data model https://github.com/mattermost/focalboard/tree/main/server/model
// https://github.com/leif81/bzkanban
// https://github.com/HigorLoren/donko (react)
// https://github.com/trobonox/kanri (GPL, Vue)
// https://github.com/waterrmalann/kards (vanilla JS)
// see also https://github.com/wekan/wekan
// see also https://taiga.io/ (for inspiration. as it is AGPL and python)
// see also https://github.com/plankanban/planka (for inspiration. as it is AGPL and React)
// see also https://kolaente.dev/vikunja/vikunja (for inspiration. AGPL. Vue and Go)
// see also https://github.com/laurent22/joplin/ (for inspiration. AGPL)
// see also https://github.com/SrGMC/kanbana
/// svelte: https://github.com/V-Py/svelte-kanban
// https://github.com/supabase-community/svelte-kanban
// https://github.com/therosbif/kanban
"prod/issue": {
"ng:crdt": "Graph",
"ng:n": "Issue",
"ng:a": "An issue to be solved",
"ng:x": {
"as":true,
"pair": "http://virtual-assembly.org/ontologies/pair#",
},
"ng:include": ["prod/task"],
"ng:compat": ["pair:Challenge"]
},
//https://github.com/go-gitea/gitea/issues/20232
// datamodel of gitea issues: https://github.com/go-gitea/gitea/blob/165346c15c6d021028a65121e692a17ffc927e2c/models/issue.go#L35-L79
"prod/form": {
"ng:crdt": "Graph",
"ng:n": "Form",
"ng:a": "A form to be filled-in",
"ng:x": {
"form" : "http://rdf.danielbeeke.nl/form/form-dev.ttl#",
},
"ng:compat": ["form:*","file/iana/application/schema+json"]
},
// https://jsonforms.io/docs/
// https://github.com/jsonform/jsonform
// https://jsonforms.io/docs/integrations/vue
// >>> https://github.com/json-editor/json-editor
// or >>> https://github.com/webgme/svelte-jsonschema-form
// or >>> https://github.com/restspace/svelte-schema-form
// see https://ceur-ws.org/Vol-1515/regular14.pdf
// and https://github.com/protegeproject/facsimile
// https://www.drupal.org/project/webform
// see https://www.semantic-mediawiki.org/wiki/Extension:Page_Forms
// https://www.mediawiki.org/wiki/Extension:Page_Forms
// https://rdf-form.danielbeeke.nl/
// consider using Shapes
"prod/filling": {
"ng:crdt": "Graph",
"ng:n": "Form filling",
"ng:a": "A form that has been filled-in",
"ng:compat": []
},
"prod/cad": { // https://mattferraro.dev/posts/cadmium
"ng:crdt": "Automerge",
"ng:n": "CAD",
"ng:a": "CADmium",
"ng:compat": []
},
"prod/slides": { //https://github.com/hakimel/reveal.js
//https://pandoc.org/MANUAL.html#slide-shows
"ng:crdt": "Graph",
"ng:n": "Slides",
"ng:a": "Slides and presentations",
"ng:include": ["post/*"],
"ng:compat": []
},
"prod/question" : {
"ng:crdt": "Graph",
"ng:n": "Question",
"ng:a": "A question that needs answers",
"ng:x": {
"as":true,
},
"ng:include": ["post/*"],
"ng:compat": ["as:Question"]
},
"prod/answer" :{
"ng:crdt": "Graph",
"ng:n": "Answer",
"ng:a": "An answer to a question",
"ng:x": {
"as":true,
},
"ng:include": ["post/*"],
"ng:compat": ["as:Note"]
},
"prod/poll" : {
"ng:crdt": "Graph",
"ng:n": "Poll",
"ng:a": "A poll where people will vote",
"ng:x": {
"as":true,
},
"ng:include": ["post/*"],
"ng:compat": ["as:Question"]
},
"prod/vote" : {
"ng:crdt": "Graph",
"ng:n": "Vote",
"ng:a": "A vote cast for a Poll",
"ng:x": {
"as":true,
},
"ng:compat": ["as:Note"]
},
"file" : {
"ng:crdt": "Graph",
"ng:n": "File",
"ng:a": "Binary file",
"ng:o": "n:g:z:file_viewer",
"ng:w": "n:g:z:file_viewer",
"ng:compat": []
},
"file/ng/wallet" : {
"ng:n": "NextGraph Wallet File",
"ng:a": "NextGraph Wallet File (.ngw)",
"ng:compat": []
},
"file/ng/doc" : {
"ng:n": "NextGraph Document File",
"ng:a": "NextGraph Document File (.ngd)",
"ng:compat": []
},
"file/ng/html" : {
"ng:n": "NextGraph Document Html",
"ng:a": "NextGraph Document Html standalone file",
"ng:compat": []
},
"file/text" : {
"ng:crdt": "Graph",
"ng:n": "File",
"ng:a": "Text file",
"ng:o": "n:g:z:file_viewer",
"ng:w": "n:g:z:file_viewer",
"ng:compat": ["file/iana/text/*", "image/svg+xml", "file/iana/application/n-quads", "file/iana/application/trig", "file/iana/application/n-triples", "file/iana/application/rdf+xml", "file/iana/application/ld+json",
"file/iana/application/xml", "file/iana/application/yaml", "file/iana/application/xhtml+xml", "file/iana/application/node","file/iana/application/sparql-results+json","file/iana/application/sparql-results+xml",
"file/iana/message/rfc822","file/iana/multipart/related", "file/iana/text/vnd.graphviz", "file/iana/application/vnd.excalidraw+json", "file/iana/application/x-tex","file/iana/text/x-tex",
"file/iana/application/vcard+json", "file/iana/application/vcard+xml", "file/iana/text/calendar", "file/iana/application/calendar+xml", "file/iana/application/calendar+json",
"file/iana/application/schema+json", "file/iana/application/geo+json", "file/iana/application/json" ]
},
};

@ -9,9 +9,92 @@
// according to those terms. // according to those terms.
--> -->
<script lang="ts">
import ng from "../api";
import { onMount, tick } from "svelte";
import { current_lang, available_languages } from "../store";
import { Language } from "svelte-heros-v2";
export let displayFooter = false;
let changingLang = false;
const changeLang = () => {
changingLang = true;
scrollToTop();
};
let top;
function scrollToTop() {
top.scrollIntoView();
}
const selectLang = async (lang) => {
current_lang.set(lang);
changingLang = false;
await tick();
scrollToTop();
};
let tauri_platform = import.meta.env.TAURI_PLATFORM;
const displayPopup = async (url, title) => {
if (!tauri_platform || tauri_platform == "android") {
window.open(url, "_blank").focus();
} else {
await ng.open_window(url, "viewer", title);
}
};
const displayNextgraphOrg = async () => {
await displayPopup("https://nextgraph.org", "NextGraph.org");
};
</script>
<div bind:this={top}>
{#if !changingLang}
<div class="centered"> <div class="centered">
<slot /> <slot />
</div> </div>
{#if displayFooter}
<div class="centered">
<div class="mb-20 mt-10">
<button
on:click={changeLang}
class="text-primary-700 bg-[#f6f6f6] bg-none ring-0 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55"
>
<Language
tabindex="-1"
class="w-7 h-7 mr-2 transition duration-75 "
/>Change language <!--note to translator: DO NOT TRANSLATE! it should stay in english always-->
</button>
<br />
<button
on:click={displayNextgraphOrg}
class="text-primary-700 bg-[#f6f6f6] bg-none ring-0 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>About NextGraph
</button>
</div>
</div>
{/if}
{:else}
<div class="centered">
<ul class="mb-20 mt-10">
{#each Object.entries(available_languages) as lang}
<li
tabindex="0"
role="menuitem"
class="flex items-center p-2 text-lg mb-2 font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={() => selectLang(lang[0])}
on:click={() => selectLang(lang[0])}
>
<span class="mx-3">{lang[1]}</span>
</li>
{/each}
</ul>
</div>
{/if}
</div>
<style> <style>
.centered { .centered {
@ -21,4 +104,7 @@
text-align: center; text-align: center;
width: fit-content; width: fit-content;
} }
li.clickable {
cursor: pointer;
}
</style> </style>

@ -0,0 +1,187 @@
<!--
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Icon,
BugAnt,
DocumentText,
Window,
CodeBracket,
SquaresPlus,
ViewfinderCircle,
ArrowsPointingOut,
Cube,
Briefcase,
MagnifyingGlass,
RocketLaunch,
Sun,
TableCells,
ListBullet,
RectangleGroup,
Squares2x2,
MapPin,
CircleStack,
Envelope,
GlobeAlt,
DocumentChartBar,
Document,
ClipboardDocumentList,
Photo,
Film,
RectangleStack,
Microphone,
MusicalNote,
Ticket,
CursorArrowRays,
Megaphone,
User,
Clock,
CalendarDays,
Calendar,
Stop,
Flag,
HandRaised,
Newspaper,
PencilSquare,
CubeTransparent,
PresentationChartBar,
QuestionMarkCircle,
CheckCircle,
ChartPie,
Bars3BottomLeft,
Link,
Square2Stack,
Clipboard,
StopCircle,
Bolt,
Heart,
} from "svelte-heros-v2";
export let config = {};
export let dataClass: string;
const exact_mapping = {
page: Window,
"app/z": SquaresPlus,
class: ViewfinderCircle,
contract: Briefcase,
"query/text": MagnifyingGlass,
"query/web": MagnifyingGlass,
"data/graph": Sun,
"data/table": TableCells,
"data/collection": ListBullet,
"data/board": RectangleGroup,
"data/grid": Squares2x2,
"data/geomap": MapPin,
"e/email": Envelope,
"mc/text": Bars3BottomLeft,
"mc/link": Link,
"plato/card": Clipboard,
"plato/pad": Square2Stack,
"media/image": Photo,
"media/reel": Film,
"media/video": Film,
"media/album": RectangleStack,
"media/audio": Microphone,
"media/song": MusicalNote,
"media/subtitle": Ticket,
"media/overlay": CursorArrowRays,
"social/channel": Megaphone,
"social/stream": Bolt,
"social/contact": User,
"social/event": Clock,
"social/calendar": CalendarDays,
"social/scheduler": Calendar,
"social/reaction": Heart,
"prod/task": Stop,
"prod/project": Flag,
"prod/issue": HandRaised,
"prod/form": Newspaper,
"prod/filling": PencilSquare,
"prod/cad": CubeTransparent,
"prod/slides": PresentationChartBar,
"prod/question": QuestionMarkCircle,
"prod/answer": CheckCircle,
"prod/poll": QuestionMarkCircle,
"prod/vote": CheckCircle,
};
const prefix_mapping = {
"post/": DocumentText,
code: CodeBracket,
schema: ArrowsPointingOut,
service: Cube,
"e/": GlobeAlt,
"app/": StopCircle,
"query/": RocketLaunch,
"data/": CircleStack,
"doc/diagram": DocumentChartBar,
"doc/chart": ChartPie,
"doc/viz": ChartPie,
"doc/": ClipboardDocumentList,
file: Document,
};
const find = (t) => {
let e = exact_mapping[t];
if (e) return e;
for (let prefix of Object.entries(prefix_mapping)) {
if (t.startsWith(prefix[0])) return prefix[1];
}
return BugAnt;
};
</script>
<!--
did:ng:n:g:z:[official apps]
did:ng:n:g:ns
did:ng:n:g:x list of context used by nextgraph
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
schema: https://schema.org/
skos: http://www.w3.org/2004/02/skos/core#
owl: http://www.w3.org/2002/07/owl#
foaf: http://xmlns.com/foaf/0.1/
relationship: http://purl.org/vocab/relationship/
dcterms: http://purl.org/dc/terms/
dcmitype: http://purl.org/dc/dcmitype/
sh: http://www.w3.org/ns/shacl#
shex: http://www.w3.org/ns/shex#
xsd: http://www.w3.org/2001/XMLSchema#
as: https://www.w3.org/ns/activitystreams#
ldp: http://www.w3.org/ns/ldp#
vcard: http://www.w3.org/2006/vcard/ns#
sec: https://w3id.org/security#
wgs: http://www.w3.org/2003/01/geo/wgs84_pos#
cc: http://creativecommons.org/ns#
gn: https://www.geonames.org/ontology#
geo: http://www.opengis.net/ont/geosparql#
time: http://www.w3.org/2006/time#
ng: did:ng:n:g:ns# or http://nextgraph.org/ns#
did:ng:n:g:ns#post/rich
ng:class => shortcut for did:ng:n:g:ns#class
a rdfs:Class
a ng:class
did:ng:o:xxxx:yy:yy
did:ng:n:xx.xx#name
did:ng:n:x: curated list of ontologies
did:ng:k common list of things (keyword)
did:ng:n:c common data
did:ng:n:z: curated list of external apps and services
http://nextgraph.org/ns# => the ng: ontology (did:ng:n:g:ns#)
ng:compat -> owl:unionOf rdf:List (alphabetical order, including itself as first element)
-->
<Icon {...config} variation="outline" color="black" icon={find(dataClass)} />

File diff suppressed because one or more lines are too long

@ -21,7 +21,7 @@
import CenteredLayout from "./CenteredLayout.svelte"; import CenteredLayout from "./CenteredLayout.svelte";
</script> </script>
<CenteredLayout> <CenteredLayout displayFooter={true}>
<div class="container3"> <div class="container3">
<div class="row"> <div class="row">
<Logo class="logo block h-40" alt="NextGraph Logo" /> <Logo class="logo block h-40" alt="NextGraph Logo" />

@ -25,6 +25,7 @@
import { link } from "svelte-spa-router"; import { link } from "svelte-spa-router";
import { onMount, onDestroy, tick } from "svelte"; import { onMount, onDestroy, tick } from "svelte";
import { Button } from "flowbite-svelte"; import { Button } from "flowbite-svelte";
import DataClassIcon from "./DataClassIcon.svelte";
let is_tauri = import.meta.env.TAURI_PLATFORM; let is_tauri = import.meta.env.TAURI_PLATFORM;

@ -0,0 +1,120 @@
<!--
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<script lang="ts">
import {
Icon,
BugAnt,
DocumentText,
Window,
CodeBracket,
SquaresPlus,
ViewfinderCircle,
ArrowsPointingOut,
Cube,
Briefcase,
MagnifyingGlass,
RocketLaunch,
Sun,
TableCells,
ListBullet,
RectangleGroup,
Squares2x2,
MapPin,
CircleStack,
Envelope,
GlobeAlt,
DocumentChartBar,
Document,
ClipboardDocumentList,
Photo,
Film,
RectangleStack,
Microphone,
MusicalNote,
Ticket,
CursorArrowRays,
Megaphone,
User,
Clock,
CalendarDays,
Calendar,
Stop,
Flag,
HandRaised,
Newspaper,
PencilSquare,
CubeTransparent,
PresentationChartBar,
QuestionMarkCircle,
CheckCircle,
ChartPie,
Bars3BottomLeft,
Link,
Square2Stack,
Clipboard,
StopCircle,
Share,
Play,
DocumentArrowDown,
DocumentArrowUp,
CloudArrowUp,
CloudArrowDown,
Beaker,
Eye,
} from "svelte-heros-v2";
export let config = {};
export let zera: string;
const exact_mapping = {
json_ld_editor: TableCells,
json_editor: TableCells,
triple_editor: Share,
rdf_viewer: CircleStack,
graph_viewer: Sun,
sparql_query: RocketLaunch,
sparnatural: CursorArrowRays,
graphql: Cube,
invoke: Play,
ontology_viewer: ArrowsPointingOut,
download: DocumentArrowDown,
post_edit: PencilSquare,
file: Document,
source: CodeBracket,
post: DocumentText,
pad: Square2Stack,
card: Clipboard,
gallery: RectangleStack,
load_graph: CloudArrowUp,
load: DocumentArrowUp,
dump: CloudArrowDown,
ext: GlobeAlt,
app_store: SquaresPlus,
app_editor: Beaker,
list: ListBullet,
grid: Squares2x2,
view: Eye,
};
const prefix_mapping = {};
const find = (t) => {
let e = exact_mapping[t];
if (e) return e;
for (let prefix of Object.entries(prefix_mapping)) {
if (t.startsWith(prefix[0])) return prefix[1];
}
return BugAnt;
};
</script>
<Icon {...config} variation="outline" color="black" icon={find(zera)} />

@ -18,15 +18,13 @@
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
import { has_wallets } from "../store"; import { has_wallets } from "../store";
let display_has_wallets_warning: boolean = $has_wallets != 0; let display_has_wallets_warning = $has_wallets != 0;
let unsubscribe; let unsubscribe;
onMount(() => {}); onMount(() => {});
onDestroy(() => { onDestroy(() => {});
unsubscribe();
});
</script> </script>
<CenteredLayout> <CenteredLayout displayFooter={true}>
<Install {display_has_wallets_warning} /> <Install {display_has_wallets_warning} />
</CenteredLayout> </CenteredLayout>

@ -19,6 +19,6 @@
<div <div
class="h-screen aspect-[3/5] pazzleline max-w-[720px] bg-yellow-300 inner" class="h-screen aspect-[3/5] pazzleline max-w-[720px] bg-yellow-300 inner"
> >
<p>nextgraph URI {params[1]}</p> <p>Nextgraph URI {params[1]}</p>
</div> </div>
</div> </div>

@ -14,7 +14,7 @@
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
</script> </script>
<CenteredLayout> <CenteredLayout displayFooter={true}>
<div class="p-8"> <div class="p-8">
<Alert color="red"> <Alert color="red">
<span class="font-medium">404</span> Page not found. <span class="font-medium">404</span> Page not found.

@ -45,7 +45,7 @@
}); });
</script> </script>
<CenteredLayout> <CenteredLayout displayFooter={true}>
<div class="container3"> <div class="container3">
<div class="row"> <div class="row">
<a href="#/"> <a href="#/">

@ -192,7 +192,7 @@
</script> </script>
<div bind:this={top}> <div bind:this={top}>
<CenteredLayout> <CenteredLayout displayFooter={!wallet}>
{#if error} {#if error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800"> <div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg <svg
@ -238,7 +238,7 @@
<Logo class="logo block h-40" alt="NextGraph Logo" /> <Logo class="logo block h-40" alt="NextGraph Logo" />
</div> </div>
<h2 class="pb-5 text-xl">Select a wallet to login with</h2> <h2 class="pb-5 text-xl">Select a wallet to login with</h2>
<div class="flex flex-wrap justify-center gap-5 mb-20"> <div class="flex flex-wrap justify-center gap-5 mb-10">
{#each Object.entries($wallets) as wallet_entry} {#each Object.entries($wallets) as wallet_entry}
<div <div
class="wallet-box" class="wallet-box"

@ -9,9 +9,129 @@
import { writable, readable, readonly, derived, get } from "svelte/store"; import { writable, readable, readonly, derived, get } from "svelte/store";
import ng from "./api"; import ng from "./api";
import { official_classes } from "./classes";
import { official_apps, official_services } from "./zeras";
let all_branches = {}; let all_branches = {};
export const available_languages = {
"en": "English",
"de": "Deutsch",
"fr": "Français",
"ru": "Русский",
"es": "Español",
"it": "Italiano",
"zh": "中文",
"pt": "Português",
};
export const current_lang = writable("en");
export const select_default_lang = async() => {
let locales = await ng.locales();
for (let lo of locales) {
if (available_languages[lo]) {
// exact match (if locales is a 2 chars lang code, or if we support regionalized translations)
current_lang.set(lo);
return;
}
lo = lo.substr(0,2);
if (available_languages[lo]) {
current_lang.set(lo);
return;
}
}
};
let loaded_external_apps = {};
export const load_app = async (appName: string) => {
if (appName.startsWith("n:g:z")) {
let app = official_apps[appName];
if (!app) throw new Error("Unknown official app");
return await import(`./apps/${app["ng:b"]}.svelte`);
} else {
//TODO: load external app from its repo
// TODO: return IFrame component
}
};
export const invoke_service = async (serviceName: string, nuri:string, args: object) => {
if (serviceName.startsWith("n:g:z")) {
let service = official_services[serviceName];
if (!service) throw new Error("Unknown official service");
// TODO: do this in WebWorker
// TODO: if on native app or CLI: use deno
//return await ng.app_invoke(serviceName[6..], nuri, args);
} else {
// TODO: if on webapp: only allow those invocations from IFrame of external app or from n:g:z:external_service_invoke (which runs in an IFrame) and run it from webworker
// TODO: if on native app or CLI: use deno
// TODO: load external service from its repo
}
};
export const cur_tab = writable({
cur_store: {
has_outer : {
nuri_trail: ":v:l"
},
type: "public", // "protected", "private", "group", "dialog",
favicon: "",
title: "Group B",
},
cur_branch: {
b: "b:xxx", //branch id (can be null if not of type "branch")
c: "c:xxx", //commit(s) id
type: "main", // "stream", "detached", "branch", "in_memory" (does not save)
display: "c:X", // or main or stream or a:xx or branch:X (only 7 chars)
attachments: 1,
class: "data/graph",
title: false,
icon: false,
description: "",
app: "n:g:z:json_ld_editor", // current app being used
},
view_or_edit: false,
graph_viewer: "n:g:z:json_ld_editor", // selected viewer
graph_editor: "n:g:z:json_ld_editor", // selected editor
discrete_viewer: "n:g:z:json_ld_editor", // selected viewer
discrete_editor: "n:g:z:json_ld_editor", // selected editor
graph_viewers: ["n:g:z:json_ld_editor"], // list of available viewers
graph_editors: ["n:g:z:json_ld_editor"], // list of available editors
discrete_viewers: [], // list of available viewers
discrete_editors: [], // list of available editors
find: false,//or string to find
graph_or_discrete: true,
read_cap: 'r:',
doc: {
is_store: false,
is_member: false,
can_edit: false,
live_edit: true,
title: "Doc A",
authors: "",
icon: "",
description: "",
stream : {
notif: 1,
last: "",
},
live_editors: {
},
},
folders_pane: false,
toc_pane: false,
right_pane: false, // "folders", "toc", "branches", "files", "history", "comments", "info", "chat"
action: false, // "view_as", "edit_with", "share", "react", "repost", "copy", "dm_author", "new_block", "notifs", "schema", "signature", "permissions", "query",
});
export const opened_wallets = writable({}); export const opened_wallets = writable({});
/// { wallet:, id: } /// { wallet:, id: }

@ -0,0 +1,629 @@
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
// "n:g:z:hide" >> hides when in viewer mode
//"n:g:z:json_ld_editor", "n:g:z:json_editor", "n:g:z:triple_editor", "n:g:z:rdf_viewer:turtle", "n:g:z:rdf_viewer:n3", "n:g:z:rdf_viewer:json_ld", "n:g:z:rdf_viewer:graph",
//"n:g:z:sparql_query:yasgui", "n:g:z:sparql_query:sparnatural", "n:g:z:graphql_query", "n:g:z:sparql_update:yasgui", "n:g:z:ontology_editor", "n:g:z:owl_viewer", "n:g:z:sparql:invoke", "n:g:z:graphql:invoke", "n:g:z:dump_download",
// "n:g:z:post_rich_editor", "n:g:z:post_md_editor", "n:g:z:code_editor", "n:g:z:file_viewer", "n:g:z:file_source", "n:g:z:crdt_source_viewer:xml", "n:g:z:crdt_source_viewer:json", "n:g:z:crdt_source_viewer:text", "n:g:z:crdt_source_viewer:rdf"
//"n:g:z:post:rich", "n:g:z:post:md", "n:g:z:text", "n:g:z:pre", "n:g:z:pad", "n:g:z:card", "n:g:z:gallery", "n:g:z:columns", "n:g:z:tree", "n:g:z:summary", "n:g:z:list", "n:g:z:grid", "n:g:z:list_n_post", "n:g:z:grid_n_post", "n:g:z:board",
//"n:g:z:map", "n:g:z:chart", "n:g:z:pivot", "n:g:z:timeline", "n:g:z:email", "n:g:z:web_archive", "n:g:z:diagram_editor", "n:g:z:pdf", "n:g:z:latex", "n:g:z:media", "n:g:z:media_editor",
//"n:g:z:service_editor", "n:g:z:service_invoke", "n:g:z:external_service_invoke", "n:g:z:contract", "n:g:z:text_query", "n:g:z:web_query", "n:g:z:scan_qrcode", "n:g:z:upload_file",
//"n:g:z:messenger", "n:g:z:group", "n:g:z:contact", "n:g:z:event", "n:g:z:calendar", "n:g:z:scheduler",
//"n:g:z:task", "n:g:z:project", "n:g:z:issue", "n:g:z:form_editor", "n:g:z:form_filler", "n:g:z:cad", "n:g:z:slides", "n:g:z:question", "n:g:z:poll",
//"n:g:z:app_store", "n:g:z:app_editor", "n:xxx.xx.xx:yy", "o:xx:yy:zz"
export const official_apps = {
"n:g:z:json_ld_editor": {
"ng:n": "JSON-LD editor",
"ng:a": "View and edit the RDF Graph as JSON-LD",
"ng:c": "app",
"ng:u": "json_ld_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_ld_editor",
"ng:b": "JsonLdEditor",
"ng:o": ["data/graph"],
"ng:w": ["data/graph"],
},
"n:g:z:json_editor": {
"ng:n": "JSON editor",
"ng:a": "View and edit your JSON data",
"ng:c": "app",
"ng:u": "json_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:json_editor",
"ng:b": "JsonEditor",
"ng:o": ["data/json","data/array","data/map"],
"ng:w": ["data/json","data/array","data/map"],
},
"n:g:z:triple_editor": {
"ng:n": "Graph triples",
"ng:a": "Edit your RDF Graph as triples",
"ng:c": "app",
"ng:u": "triple_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:triple_editor",
"ng:b": "TripleEditor",
"ng:o": ["data/graph"],
"ng:w": ["data/graph"],
},
"n:g:z:rdf_viewer:turtle": { // https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "Turtle",
"ng:a": "View your RDF Graph in Turtle format",
"ng:c": "app",
"ng:u": "rdf_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:turtle",
"ng:b": "TurtleViewer",
"ng:o": ["data/graph"],
"ng:w": [],
},
"n:g:z:rdf_viewer:n3": { // ?
"ng:n": "N3",
"ng:a": "View your RDF Graph in N3 format",
"ng:c": "app",
"ng:u": "rdf_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:n3",
"ng:b": "N3Viewer",
"ng:o": ["data/graph"],
"ng:w": [],
},
"n:g:z:rdf_viewer:json_ld": { // highlight.js JSON
"ng:n": "JSON-LD",
"ng:a": "View your RDF Graph in N3 format",
"ng:c": "app",
"ng:u": "rdf_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:json_ld",
"ng:b": "JsonLdViewer",
"ng:o": ["data/graph"],
"ng:w": [],
},
"n:g:z:rdf_viewer:graph": {
"ng:n": "Graph Explorer",
"ng:a": "View your RDF Graph as interactive visualization",
"ng:c": "app",
"ng:u": "graph_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:rdf_viewer:graph",
"ng:b": "GraphViewer", // GraphExplorer https://github.com/zazuko/graph-explorer !! AGPL
"ng:o": ["data/graph"],
"ng:w": [],
},
"n:g:z:sparql_query:yasgui": {
"ng:n": "SPARQL Query",
"ng:a": "View, edit and invoke your Graph SPARQL query",
"ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query:yasgui",
"ng:b": "SparqlQueryEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": [],
"ng:w": ["query/sparql"],
},
"n:g:z:sparql_query:sparnatural": {
"ng:n": "SPARQL natural Query",
"ng:a": "View, edit and invoke your Graph SPARQL query with SPARnatural tool",
"ng:c": "app",
"ng:u": "sparnatural",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query:sparnatural",
"ng:b": "SparNaturalEditor",
"ng:o": [],
"ng:w": ["query/sparql"],
},
"n:g:z:graphql_query": {
"ng:n": "GraphQL Query",
"ng:a": "View, edit and invoke your GraphQL query",
"ng:c": "app",
"ng:u": "graphql",//favicon. can be a did:ng:j
"ng:g": "n:g:z:graphql_query",
"ng:b": "GraphqlEditor",
"ng:o": [],
"ng:w": ["query/graphql"],
},
"n:g:z:sparql_update:yasgui": {
"ng:n": "SPARQL Update",
"ng:a": "View, edit and invoke your Graph SPARQL Update",
"ng:c": "app",
"ng:u": "sparql_query",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_update:yasgui",
"ng:b": "SparqlUpdateEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
"ng:o": [],
"ng:w": ["query/sparql_update"],
},
"n:g:z:ontology_editor": {
"ng:n": "Ontology editor",
"ng:a": "Edit your Ontology",
"ng:c": "app",
"ng:u": "json_ld_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:ontology_editor",
"ng:b": "JsonLdEditor",
"ng:o": [],
"ng:w": ["schema/*"],
},
"n:g:z:owl_viewer": {
"ng:n": "OWL Ontology",
"ng:a": "View your OWL Ontology",
"ng:c": "app",
"ng:u": "ontology_viewer",//favicon. can be a did:ng:j
"ng:g": "n:g:z:owl_viewer",
"ng:b": "OwlViewer", // display with https://github.com/VisualDataWeb/WebVOWL
"ng:o": ["schema/owl"],
"ng:w": [],
},
"n:g:z:sparql:invoke": { // displayed with highlight.js https://github.com/highlightjs/highlightjs-turtle/tree/master
"ng:n": "SPARQL Invoke",
"ng:a": "View and invoke your saved SPARQL query",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql:invoke",
"ng:b": "SparqlInvoker",
"ng:o": ["query/sparql","query/sparql_update"],
"ng:w": [],
},
"n:g:z:graphql:invoke": {
"ng:n": "GraphQL Invoke",
"ng:a": "View and invoke your saved GraphQL query",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:graphql:invoke",
"ng:b": "GraphqlInvoker",
"ng:o": ["query/graphql"],
"ng:w": [],
},
"n:g:z:dump_download": {
"ng:n": "Download",
"ng:a": "Download a file containing a document export data",
"ng:c": "app",
"ng:u": "download",//favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_download",
"ng:b": "Downloader",
"ng:o": ["data/graph","file*","data/*"],
"ng:w": [],
},
"n:g:z:post_rich_editor": {
"ng:n": "Post Editor",
"ng:a": "Edit your post with ProseMirror",
"ng:c": "app",
"ng:u": "post_edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post_rich_editor",
"ng:b": "ProseMirrorEditor",
"ng:o": [],
"ng:w": ["post/rich"],
},
"n:g:z:post_md_editor": {
"ng:n": "Post Editor",
"ng:a": "Edit your post with MilkDown",
"ng:c": "app",
"ng:u": "post_edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post_md_editor",
"ng:b": "MilkDownEditor",
"ng:o": [],
"ng:w": ["post/md"],
},
"n:g:z:code_editor": {
"ng:n": "Code and Text Editor",
"ng:a": "Edit your code/text with CodeMirror",
"ng:c": "app",
"ng:u": "post_edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:code_editor",
"ng:b": "CodeMirrorEditor",
"ng:o": [],
"ng:w": ["code*","post/text"],
},
"n:g:z:file_viewer": {
"ng:n": "File details",
"ng:a": "See details about this file",
"ng:c": "app",
"ng:u": "file",//favicon. can be a did:ng:j
"ng:g": "n:g:z:file_viewer",
"ng:b": "FileDetails",
"ng:o": ["file*"],
"ng:w": ["file*"], // in editor mode: can change the name, and delete the file
},
"n:g:z:file_source": { // only works for files containing text source (SVG, HTML, JS, CSS, etc...)
"ng:n": "File source",
"ng:a": "See the source code of this file",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:file_source",
"ng:b": "FileSource",
"ng:o": ["file/text"],
"ng:w": [],
},
"n:g:z:crdt_source_viewer:xml": {
"ng:n": "XML source",
"ng:a": "See the source code of this document, in XML",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:xml",
"ng:b": "XmlSource", // displayed with highlight.js , with option to download
"ng:o": ["post/rich","post/md","post/html","page","data/xml", "doc/diagram/drawio"],
"ng:w": [],
},
"n:g:z:crdt_source_viewer:json": {
"ng:n": "JSON source",
"ng:a": "See the source code of this document, in JSON",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:json",
"ng:b": "JsonSource", // displayed with highlight.js , with option to download
"ng:o": ["data/json", "data/map", "data/array", "data/table", "doc/diagram/jsmind", "doc/diagram/gantt", "doc/diagram/excalidraw", "doc/viz/*", "doc/chart/*", "prod/cad"],
"ng:w": [],
},
"n:g:z:crdt_source_viewer:text": {
"ng:n": "Text source",
"ng:a": "See the source code of this document, in plain-text",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:text",
"ng:b": "TextViewer", // displayed with highlight.js , with option to download
"ng:o": ["post/text", "post/asciidoc", "code*", "service*", "contract", "query/sparql*","query/graphql","doc/diagram/mermaid","doc/diagram/graphviz","doc/diagram/flowchart",
"doc/diagram/sequence","doc/diagram/markmap","doc/diagram/mymind","doc/music*", "doc/maths", "doc/chemistry", "doc/ancientscript", "doc/braille", "media/subtitle"],
"ng:w": [],
},
"n:g:z:crdt_source_viewer:rdf": {
"ng:n": "RDF source",
"ng:a": "See the source graph of this document, in RDF (turtle)",
"ng:c": "app",
"ng:u": "source",//favicon. can be a did:ng:j
"ng:g": "n:g:z:crdt_source_viewer:rdf",
"ng:b": "TurtleViewer", //, with option to download
"ng:o": ["data/graph"],
"ng:w": [],
},
"n:g:z:post:rich": {
"ng:n": "Post",
"ng:a": "View a Rich Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:rich",
"ng:b": "PostRichViewer", // https://www.npmjs.com/package/prosemirror-to-html-js or https://prosemirror.net/docs/ref/version/0.4.0.html#toDOM https://prosemirror.net/docs/ref/version/0.4.0.html#toHTML
"ng:o": ["post/rich"],
"ng:w": [],
},
"n:g:z:post:md": {
"ng:n": "Post",
"ng:a": "View a Markdown Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:md",
"ng:b": "PostMdViewer", // https://github.com/wooorm/markdown-rs
"ng:o": ["post/md"],
"ng:w": [],
},
"n:g:z:post:text": {
"ng:n": "Text",
"ng:a": "View a Text Post",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:post:text",
"ng:b": "TextViewer", // displayed with a <p>
"ng:o": ["post/text"],
"ng:w": [],
},
"n:g:z:pre": {
"ng:n": "Source Code",
"ng:a": "View a Source Code",
"ng:c": "app",
"ng:u": "post",//favicon. can be a did:ng:j
"ng:g": "n:g:z:pre",
"ng:b": "PreTextViewer", // displayed with highlight.js
"ng:o": ["code*","post/text"],
"ng:w": [],
},
"n:g:z:pad": {
"ng:n": "Pad",
"ng:a": "Pad view of a document",
"ng:c": "app",
"ng:u": "pad",//favicon. can be a did:ng:j
"ng:g": "n:g:z:pad",
"ng:b": "Pad",
"ng:o": ["plato/pad"],
"ng:w": [],
},
"n:g:z:card": {
"ng:n": "Card",
"ng:a": "Card view of a document",
"ng:c": "app",
"ng:u": "card",//favicon. can be a did:ng:j
"ng:g": "n:g:z:card",
"ng:b": "Card",
"ng:o": ["plato/card"],
"ng:w": [],
},
"n:g:z:gallery": {
"ng:n": "Gallery",
"ng:a": "Gallery view of an album or collection",
"ng:c": "app",
"ng:u": "gallery",//favicon. can be a did:ng:j
"ng:g": "n:g:z:gallery",
"ng:b": "Gallery",
"ng:o": ["media/album","data/collection"],
"ng:w": [],
},
"n:g:z:app_store": {
"ng:n": "App Store",
"ng:a": "Install or remove Apps of NextGraph ecosystem",
"ng:c": "app",
"ng:u": "app_store",//favicon. can be a did:ng:j
"ng:g": "n:g:z:app_store",
"ng:b": "AppStore",
"ng:o": ["app/z"],
"ng:w": [],
},
"n:g:z:app_editor": {
"ng:n": "App editor",
"ng:a": "Create and modify your App with NextGraph IDE",
"ng:c": "app",
"ng:u": "app_editor",//favicon. can be a did:ng:j
"ng:g": "n:g:z:app_editor",
"ng:b": "AppEditor",
"ng:o": ["app/z"],
"ng:w": ["app/z"],
},
"n:g:z:list": {
"ng:n": "List view",
"ng:a": "See the content of document as a list",
"ng:c": "app",
"ng:u": "list",//favicon. can be a did:ng:j
"ng:g": "n:g:z:list",
"ng:b": "ListView",
"ng:o": ["data/graph"],
"ng:w": ["data/graph"],
},
"n:g:z:grid": {
"ng:n": "Grid view",
"ng:a": "See the content of document as a grid",
"ng:c": "app",
"ng:u": "grid",//favicon. can be a did:ng:j
"ng:g": "n:g:z:grid",
"ng:b": "GridView",
"ng:o": ["data/graph"],
"ng:w": ["data/graph"],
},
"n:g:z:media": {
"ng:n": "Media view",
"ng:a": "View media",
"ng:c": "app",
"ng:u": "view",//favicon. can be a did:ng:j
"ng:g": "n:g:z:media",
"ng:b": "MediaView",
"ng:o": ["media/*"],
"ng:w": [],
},
"n:g:z:service_editor": {
"ng:n": "Service Editor",
"ng:a": "Write and define your Service in Rust or JS/Deno",
"ng:c": "app",
"ng:u": "post_edit",//favicon. can be a did:ng:j
"ng:g": "n:g:z:service_editor",
"ng:b": "CodeMirrorEditor",
"ng:o": [],
"ng:w": ["service/*"],
},
"n:g:z:service_invoke": {
"ng:n": "Service Invoker",
"ng:a": "Invoke internal Service, with optional arguments",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:service_invoke",
"ng:b": "ServiceInvoker",
"ng:o": ["service"],
"ng:w": [],
},
"n:g:z:external_service_invoke": {
"ng:n": "Service Invoker",
"ng:a": "Invoke the Service, with optional arguments",
"ng:c": "app",
"ng:u": "invoke",//favicon. can be a did:ng:j
"ng:g": "n:g:z:external_service_invoke",
"ng:b": "ExternalServiceInvoker",
"ng:o": ["service/*"],
"ng:w": [],
},
"n:g:z:upload_file": {
"ng:n": "Upload file",
"ng:a": "Upload a binary file into a document",
"ng:c": "app",
"ng:u": "load",//favicon. can be a did:ng:j
"ng:g": "n:g:z:upload_file",
"ng:b": "UploadFile",
"ng:o": [],
"ng:w": ["data/graph"],
},
// TODO: "n:g:z:columns", "n:g:z:tree", "n:g:z:summary", "n:g:z:list_n_post", "n:g:z:grid_n_post", "n:g:z:board",
// TODO: "n:g:z:map", "n:g:z:chart", "n:g:z:pivot", "n:g:z:timeline", "n:g:z:email", "n:g:z:web_archive", "n:g:z:diagram_editor", "n:g:z:pdf", "n:g:z:latex", "n:g:z:media_editor",
// TODO: "n:g:z:contract", "n:g:z:text_query", "n:g:z:web_query", "n:g:z:scan_qrcode",
// TODO: "n:g:z:messenger", "n:g:z:group", "n:g:z:contact", "n:g:z:event", "n:g:z:calendar", "n:g:z:scheduler",
// TODO: "n:g:z:task", "n:g:z:project", "n:g:z:issue", "n:g:z:form_editor", "n:g:z:form_filler", "n:g:z:cad", "n:g:z:slides", "n:g:z:question", "n:g:z:poll",
};
// OFFICIAL SERVICES
//"n:g:z:dump_rdf:turtle", "n:g:z:dump_rdf:n3", "n:g:z:dump_rdf:json_ld", "n:g:z:load_rdf:turtle", "n:g:z:load_rdf:n3", "n:g:z:load_rdf:json_ld", "n:g:z:load_file", "n:g:z:dump_file",
//"n:g:z:dump_json", "n:g:z:dump_xml", "n:g:z:dump_text", "n:g:z:load_json", "n:g:z:load_xml", "n:g:z:load_text", "n:g:z:load_md", "n:g:z:sparql_query", "n:g:z:sparql_update", "n:g:z:dump_crdt_source", "n:g:z:dump_ng_html_file", "n:g:z:dump_ng_file"
export const official_services = {
"n:g:z:dump_rdf:turtle": {
"ng:n": "Turtle export",
"ng:a": "Export quads of RDF Graphs in Turtle format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:turtle",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/text/turtle"],
},
"n:g:z:dump_rdf:n3": {
"ng:n": "N3 export",
"ng:a": "Export quads of RDF Graphs in N3 format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:n3",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/text/n3"],
},
"n:g:z:dump_rdf:json_ld": {
"ng:n": "JSON-LD export",
"ng:a": "Export quads of RDF Graphs in JSON-LD format",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_rdf:json_ld",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/application/ld+json"],
},
"n:g:z:load_rdf:turtle": {
"ng:n": "Import Turtle triples",
"ng:a": "Import Turtle triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:turtle",
"ng:o": [],
"ng:w": ["data/graph"],
},
"n:g:z:load_rdf:n3": {
"ng:n": "Import N3 triples",
"ng:a": "Import N3 triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:n3",
"ng:o": [],
"ng:w": ["data/graph"],
},
"n:g:z:load_rdf:json_ld": {
"ng:n": "Import JSON-LD triples",
"ng:a": "Import JSON-LD triples into the document",
"ng:c": "service",
"ng:u": "load_graph",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_rdf:json_ld",
"ng:o": [],
"ng:w": ["data/graph"],
},
"n:g:z:load_file": {
"ng:n": "Add file",
"ng:a": "Add a binary file in the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_file",
"ng:o": [],
"ng:w": ["data/graph"],
},
"n:g:z:dump_file": {
"ng:n": "Export file",
"ng:a": "Get the binary content of a file",
"ng:c": "service",
"ng:u": "dump",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_file",
"ng:o": ["file*"],
"ng:result": ["file/iana/*"],
},
"n:g:z:dump_json": {
"ng:n": "JSON export",
"ng:a": "Export JSON content of document",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_json",
"ng:o": ["data/json", "data/map", "data/array", "data/table", "doc/diagram/jsmind", "doc/diagram/gantt", "doc/diagram/excalidraw", "doc/viz/*", "doc/chart/*", "prod/cad"],
"ng:w": [],
"ng:result": ["file/iana/application/json"],
},
"n:g:z:dump_xml": {
"ng:n": "XML export",
"ng:a": "Export XML content of document",
"ng:c": "service",
"ng:u": "data",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_xml",
"ng:o": ["post/rich","post/md","post/html","page","data/xml", "doc/diagram/drawio"],
"ng:w": [],
"ng:result": ["file/iana/text/xml"],
},
"n:g:z:dump_text": {
"ng:n": "Text export",
"ng:a": "Export plain-text content of document",
"ng:c": "service",
"ng:u": "dump",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_text",
"ng:o": ["post/text", "post/asciidoc", "code*", "service*", "contract", "query/sparql*","query/graphql","doc/diagram/mermaid","doc/diagram/graphviz","doc/diagram/flowchart",
"doc/diagram/sequence","doc/diagram/markmap","doc/diagram/mymind","doc/music*", "doc/maths", "doc/chemistry", "doc/ancientscript", "doc/braille", "media/subtitle"],
"ng:w": [],
"ng:result": ["file/iana/text/plain"],
},
"n:g:z:dump_ng_html_file": {
"ng:n": "NextGraph Standalone file",
"ng:a": "Get a standalone HTML file of this Document",
"ng:c": "service",
"ng:u": "ext",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_ng_html_file",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/text/html"],
},
"n:g:z:load_json": {
"ng:n": "Import JSON",
"ng:a": "Import some JSON into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_json",
"ng:o": [],
"ng:w": ["data/json","data/map", "data/array"],
},
"n:g:z:load_xml": {
"ng:n": "Import XML",
"ng:a": "Import some XML into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_xml",
"ng:o": [],
"ng:w": ["data/xml"],
},
"n:g:z:load_text": {
"ng:n": "Import Text",
"ng:a": "Import some text into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_text",
"ng:o": [],
"ng:w": ["post/text","post/rich","post/md"],
},
"n:g:z:load_md": {
"ng:n": "Import Markdown",
"ng:a": "Import some Markdown into the document",
"ng:c": "service",
"ng:u": "load",// favicon. can be a did:ng:j
"ng:g": "n:g:z:load_md",
"ng:o": [],
"ng:w": ["post/md"],
},
"n:g:z:sparql_query": {
"ng:n": "SPARQL query",
"ng:a": "Invoke a SPARQL Query",
"ng:c": "service",
"ng:u": "sparql_query",// favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_query",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/application/sparql-results+json","file/iana/application/json"]
},
"n:g:z:sparql_update": {
"ng:n": "SPARQL update",
"ng:a": "Invoke a SPARQL Update",
"ng:c": "service",
"ng:u": "sparql_query",// favicon. can be a did:ng:j
"ng:g": "n:g:z:sparql_update",
"ng:o": [],
"ng:w": ["data/graph"],
},
"n:g:z:dump_crdt_source": { // uses dump_rdf, dump_text, dump_json or dump_xml depending on the CRDT type
"ng:n": "Export source",
"ng:a": "Export source of document as text file",
"ng:c": "service",
"ng:u": "source",// favicon. can be a did:ng:j
"ng:g": "n:g:z:dump_crdt_source",
"ng:o": ["data/graph"],
"ng:w": [],
"ng:result": ["file/iana/*"]
},
};

@ -560,7 +560,7 @@ pub struct DocAddFile {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DocCreate { pub struct DocCreate {
store: StoreRepo, store: StoreRepo,
content_type: BranchContentType, class: String,
} }
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -579,7 +579,7 @@ pub enum AppRequestPayloadV0 {
Delete(DocDelete), Delete(DocDelete),
//Invoke(InvokeArguments), //Invoke(InvokeArguments),
SmallFilePut(SmallFile), SmallFilePut(SmallFile),
RandomAccessFilePut(String), // content_type RandomAccessFilePut(String), // content_type (iana media type)
RandomAccessFilePutChunk((u32, serde_bytes::ByteBuf)), // end the upload with an empty vec RandomAccessFilePutChunk((u32, serde_bytes::ByteBuf)), // end the upload with an empty vec
} }

@ -214,9 +214,7 @@ impl<'a, 'b: 'a> SimpleUpdateEvaluator<'a, 'b> {
GraphName::NamedNode(graph_name) => graph_name.into(), GraphName::NamedNode(graph_name) => graph_name.into(),
GraphName::DefaultGraph => { GraphName::DefaultGraph => {
if let Some(default_graph) = &self.options.query_options.default_graph { if let Some(default_graph) = &self.options.query_options.default_graph {
crate::oxrdf::GraphNameRef::NamedNode(NamedNodeRef::new_unchecked( GraphNameRef::NamedNode(NamedNodeRef::new_unchecked(&default_graph))
&default_graph,
))
} else { } else {
return Err(EvaluationError::NoDefaultGraph); return Err(EvaluationError::NoDefaultGraph);
} }

@ -1293,7 +1293,7 @@ pub enum Quorum {
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum BranchContentType { pub enum BranchContentType {
GraphOnly, Graph,
YMap, YMap,
YXml, YXml,
YText, YText,
@ -1302,8 +1302,7 @@ pub enum BranchContentType {
//Owl, //Owl,
//Shacl, //Shacl,
//Shex, //Shex,
None, // this is used by Store, Overlay and User BranchTypes None, // this is used by Overlay and User BranchTypes
//Chat,
} }
/// Branch definition /// Branch definition

@ -230,3 +230,31 @@ pub fn display_timestamp(ts: &Timestamp) -> String {
} }
pub(crate) type Receiver<T> = mpsc::UnboundedReceiver<T>; pub(crate) type Receiver<T> = mpsc::UnboundedReceiver<T>;
#[cfg(test)]
mod test {
use crate::log::*;
#[test]
pub fn test_locales() {
let list = vec!["C", "c", "aa-bb-cc-dd", "aa-ff_bb.456d"];
let res: Vec<String> = list
.iter()
.filter_map(|lang| {
if *lang == "C" || *lang == "c" {
None
} else {
let mut split = lang.split('.');
let code = split.next().unwrap();
let code = code.replace("_", "-");
let mut split = code.rsplitn(2, '-');
let country = split.next().unwrap();
Some(match split.next() {
Some(next) => format!("{}-{}", next, country.to_uppercase()),
None => country.to_string(),
})
}
})
.collect();
log_debug!("{:?}", res);
}
}

@ -29,6 +29,7 @@ once_cell = "1.17.1"
getrandom = { version = "0.1.1", features = ["wasm-bindgen"] } getrandom = { version = "0.1.1", features = ["wasm-bindgen"] }
rand = { version = "0.7", features = ["getrandom"] } rand = { version = "0.7", features = ["getrandom"] }
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] } wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
sys-locale = { version = "0.3.1", features = ["js"] }
ng-repo = { path = "../ng-repo" } ng-repo = { path = "../ng-repo" }
ng-net = { path = "../ng-net" } ng-net = { path = "../ng-net" }
ng-client-ws = { path = "../ng-client-ws" } ng-client-ws = { path = "../ng-client-ws" }

@ -26,6 +26,7 @@ use serde_json::json;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use js_sys::Array; use js_sys::Array;
use oxrdf::Triple; use oxrdf::Triple;
use sys_locale::get_locales;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::future_to_promise; use wasm_bindgen_futures::future_to_promise;
use wasm_bindgen_futures::JsFuture; use wasm_bindgen_futures::JsFuture;
@ -54,6 +55,11 @@ use nextgraph::local_broker::*;
use crate::model::*; use crate::model::*;
#[wasm_bindgen]
pub async fn locales() -> Result<JsValue, JsValue> {
Ok(serde_wasm_bindgen::to_value(&get_locales().collect::<Vec<_>>()).unwrap())
}
#[wasm_bindgen] #[wasm_bindgen]
pub async fn get_local_bootstrap(location: String, invite: JsValue) -> JsValue { pub async fn get_local_bootstrap(location: String, invite: JsValue) -> JsValue {
let res = retrieve_local_bootstrap(location, invite.as_string(), false).await; let res = retrieve_local_bootstrap(location, invite.as_string(), false).await;

@ -375,7 +375,7 @@
</div> </div>
</div> </div>
{#if ca} {#if ca}
<div class="row mb-20"> <div class="row mb-10">
<button <button
on:click|once={accept} on:click|once={accept}
class="mr-5 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2" class="mr-5 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"

@ -154,7 +154,7 @@
</ul> </ul>
</div> </div>
</div> </div>
<div class="row mb-20"> <div class="row mb-10">
<button <button
on:click|once={accept} on:click|once={accept}
class="mr-5 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2" class="mr-5 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"

@ -21,7 +21,7 @@
onMount(() => {}); onMount(() => {});
onDestroy(() => { onDestroy(() => {
unsubscribe(); //unsubscribe();
}); });
</script> </script>

Loading…
Cancel
Save