diff --git a/nextgraph/src/lib.rs b/nextgraph/src/lib.rs
index c0e9511..94df7cf 100644
--- a/nextgraph/src/lib.rs
+++ b/nextgraph/src/lib.rs
@@ -94,6 +94,7 @@ pub mod verifier {
         pub use ng_net::app_protocol::*;
     }
     pub use ng_verifier::prepare_app_response_for_js;
+    pub use ng_verifier::triples_ser_to_json_string;
 }
 
 pub mod wallet {
diff --git a/ng-app/package.json b/ng-app/package.json
index cd5c96d..a932bb0 100644
--- a/ng-app/package.json
+++ b/ng-app/package.json
@@ -44,6 +44,7 @@
     "autoprefixer": "^10.4.14",
     "cross-env": "^7.0.3",
     "dayjs": "^1.11.10",
+    "highlight.js": "^11.10.0",
     "internal-ip": "^7.0.0",
     "node-gzip": "^1.1.2",
     "postcss": "^8.4.23",
@@ -52,6 +53,7 @@
     "svelte": "^3.54.0",
     "svelte-check": "^3.0.0",
     "svelte-heros-v2": "^0.10.12",
+    "svelte-highlight": "^7.7.0",
     "svelte-preprocess": "^5.0.3",
     "svelte-time": "^0.8.0",
     "tailwindcss": "^3.3.1",
diff --git a/ng-app/src/apps/SparqlQueryEditor.svelte b/ng-app/src/apps/SparqlQueryEditor.svelte
new file mode 100644
index 0000000..f0e5440
--- /dev/null
+++ b/ng-app/src/apps/SparqlQueryEditor.svelte
@@ -0,0 +1,119 @@
+<!--
+// 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 { onMount, tick, onDestroy } from "svelte";
+    import { 
+      sparql_query,
+      toast_error,
+      toast_success,
+      reset_toasts
+    } from "../store";
+    import { 
+      in_memory_discrete, open_viewer, set_viewer
+    } from "../tab";
+    import{ Sun, RocketLaunch } from "svelte-heros-v2";
+    import { t } from "svelte-i18n";
+
+    import { Table, TableBody, TableBodyCell, TableBodyRow, TableHead, TableHeadCell, Toggle } from 'flowbite-svelte';
+    
+    import CodeMirror from "svelte-codemirror-editor";
+    import {StreamLanguage} from "@codemirror/language"
+    import { sparql } from "@codemirror/legacy-modes/mode/sparql";
+    import {basicSetup} from "codemirror"
+
+    import Highlight, { LineNumbers } from "svelte-highlight";
+    import hljs from "highlight.js";
+    import { definer } from "../turtle";
+    import "svelte-highlight/styles/github.css";
+    import { each } from "svelte/internal";
+    const language = {
+      name: "turtle",
+      register: (hljs) => {
+        return definer(hljs);
+      },
+    };
+
+    onMount(()=>{
+        if (!$in_memory_discrete){
+            $in_memory_discrete = "SELECT ?subject ?predicate ?object WHERE {\n   ?subject ?predicate ?object .\n} LIMIT 10";
+        }
+    });
+    let union = false;
+    const run = async () => {
+      try{
+        reset_toasts();
+        results = await sparql_query($in_memory_discrete, union);
+      } catch(e) {
+        toast_error(e);
+      }
+    }
+    const openTurtle = () => {
+      reset_toasts();
+      set_viewer("n:g:z:rdf_viewer:turtle");
+    }
+    let results = undefined;
+  
+  </script>
+  <div class="flex-col">
+    
+    <CodeMirror bind:value={$in_memory_discrete} lineWrapping useTab={false} extensions={[basicSetup,StreamLanguage.define(sparql)]} styles={{
+      "&": {
+          maxWidth: "100%",
+      },
+    }}/>
+    <Toggle class="mt-1 ml-2" bind:checked={union}>Query all docs</Toggle>
+    <button
+      on:click={run}
+      on:keypress={run}
+      class="select-none ml-2 mt-2 mb-10 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
+    >
+      <RocketLaunch tabindex="-1" class="mr-2 focus:outline-none" />
+      Run Query
+    </button>
+    <button
+      on:click={openTurtle}
+      on:keypress={openTurtle}
+      class="select-none ml-2 mt-2 mb-10 text-gray-600  focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
+    >
+      <Sun class="mr-2 focus:outline-none" tabindex="-1" />
+      View Graph
+    </button>
+    {#if results!==undefined}
+      <div>
+        <span class="ml-2 font-bold">Results: <br/></span>
+        {#if Array.isArray(results)}
+          <Highlight {language} code={results.join(" .\r\n") + " ."} class="mb-10"  let:highlighted >
+            <LineNumbers {highlighted} wrapLines hideBorder />
+          </Highlight>
+        {:else if results?.head} 
+          <Table>
+            <TableHead>
+              {#each results.head.vars as variable}
+              <TableHeadCell>{variable}</TableHeadCell>
+              {/each}
+            </TableHead>
+            <TableBody tableBodyClass="divide-y">
+              {#each results.results.bindings as row}
+                <TableBodyRow>
+                  {#each results.head.vars as variable}
+                    <TableBodyCell class="px-6 py-4 whitespace-break-spaces font-medium">{row[variable].value}</TableBodyCell>
+                  {/each}
+                </TableBodyRow>
+              {/each}
+            </TableBody>
+          </Table>
+        {:else}
+          <span class="ml-2">{results}</span>
+        {/if}
+      </div>
+    {/if}
+  </div>
\ No newline at end of file
diff --git a/ng-app/src/apps/SparqlUpdateEditor.svelte b/ng-app/src/apps/SparqlUpdateEditor.svelte
index 6210dfa..b062982 100644
--- a/ng-app/src/apps/SparqlUpdateEditor.svelte
+++ b/ng-app/src/apps/SparqlUpdateEditor.svelte
@@ -14,7 +14,8 @@
     import { 
       sparql_update,
       toast_error,
-      toast_success
+      toast_success,
+      reset_toasts,
     } from "../store";
     import { 
       in_memory_discrete, open_viewer
@@ -29,22 +30,23 @@
     import { sparql } from "@codemirror/legacy-modes/mode/sparql";
     import {basicSetup} from "codemirror"
     onMount(()=>{
-        if (!$in_memory_discrete){
-            $in_memory_discrete = "INSERT DATA { \n  <did:ng:test> <test:predicate> \"An example value\".\r}";
-            
-//             "SELECT * WHERE {\r\
-//   ?subject ?predicate ?object .\r\
-// } LIMIT 10";
-        }
+      if (!$in_memory_discrete){
+        $in_memory_discrete = "INSERT DATA { \n  <did:ng:test> <test:predicate> \"An example value\".\r}";
+      }
     });
     const run = async () => {
       try{
+        reset_toasts();
         await sparql_update($in_memory_discrete);
         toast_success($t("app.sparql_update_editor.success"));
       } catch(e) {
         toast_error(e);
       }
     }
+    const openViewer = () => {
+      reset_toasts();
+      open_viewer();
+    }
   
   </script>
   <div class="flex-col">
@@ -63,8 +65,8 @@
       Run Update
     </button>
     <button
-      on:click={open_viewer}
-      on:keypress={open_viewer}
+      on:click={openViewer}
+      on:keypress={openViewer}
       class="select-none ml-2 mt-2 mb-10 text-gray-600  focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
     >
       <Sun class="mr-2 focus:outline-none" tabindex="-1" />
diff --git a/ng-app/src/apps/TurtleViewer.svelte b/ng-app/src/apps/TurtleViewer.svelte
new file mode 100644
index 0000000..a3ab4ef
--- /dev/null
+++ b/ng-app/src/apps/TurtleViewer.svelte
@@ -0,0 +1,81 @@
+<!--
+// 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 { onMount, tick, onDestroy } from "svelte";
+    import { 
+      sparql_update,
+      toast_error,
+      toast_success
+    } from "../store";
+    import { 
+      in_memory_discrete, open_viewer, set_viewer, set_editor, set_view_or_edit, cur_tab
+    } from "../tab";
+    import{ PencilSquare, RocketLaunch } from "svelte-heros-v2";
+    import { t } from "svelte-i18n";
+    import { Button, Progressbar, Spinner, Alert } from "flowbite-svelte";
+    
+    import Highlight, { LineNumbers } from "svelte-highlight";
+    import hljs from "highlight.js";
+    import { definer } from "../turtle";
+    import "svelte-highlight/styles/github.css";
+    const language = {
+      name: "turtle",
+      register: (hljs) => {
+        return definer(hljs);
+      },
+    };
+    
+    export let commits = {graph:[]};
+    let source = "";
+    $: source = commits.graph.join(" .\r\n") + " .";
+
+    const openQuery = () => {
+      set_viewer("n:g:z:sparql_query");
+    }
+    const openUpdate = () => {
+      set_editor("n:g:z:sparql_update");
+      set_view_or_edit(false);
+    }
+
+    onMount(()=>{
+        
+    });
+  
+  </script>
+  <div class="flex-col">
+    
+    <button
+      on:click={openQuery}
+      on:keypress={openQuery}
+      class="select-none ml-2 mt-2 mb-2 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
+    >
+      <RocketLaunch tabindex="-1" class="mr-2 focus:outline-none" />
+      SPARQL Query
+    </button>
+    {#if $cur_tab.doc.can_edit}
+      <button
+        on:click={openUpdate}
+        on:keypress={openUpdate}
+        class="select-none ml-2 mt-2  text-gray-600  focus:ring-4 focus:ring-primary-500/50 rounded-lg text-base p-2 text-center inline-flex items-center dark:focus:ring-primary-700/55"
+      >
+        <PencilSquare class="mr-2 focus:outline-none" tabindex="-1" />
+        SPARQL Update
+      </button>
+    {/if}
+
+    <Highlight {language} code={source} class="mb-10"  let:highlighted >
+      <LineNumbers {highlighted} wrapLines hideBorder />
+    </Highlight>
+
+      
+  </div>
+  
\ No newline at end of file
diff --git a/ng-app/src/classes.ts b/ng-app/src/classes.ts
index acb3bfc..115b96e 100644
--- a/ng-app/src/classes.ts
+++ b/ng-app/src/classes.ts
@@ -200,7 +200,7 @@ export const official_classes = {
         "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:w": "n:g:z:sparql_query",
         "ng:compat": ["code:sparql", "file:iana:application:sparql-query","file:iana:application:x-sparql-query"],
     },
     "query:sparql_update": { 
@@ -208,7 +208,7 @@ export const official_classes = {
         "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:w": "n:g:z:sparql_update",
         "ng:compat": ["code:sparql", "file:iana:application:sparql-update"],
     },
     "query:graphql": {
diff --git a/ng-app/src/locales/en.json b/ng-app/src/locales/en.json
index 9095456..b10a5a0 100644
--- a/ng-app/src/locales/en.json
+++ b/ng-app/src/locales/en.json
@@ -218,7 +218,7 @@
       "remove_wallet": "Remove wallet from Device",
       "remove_wallet_modal.title": "Remove wallet?",
       "remove_wallet_modal.confirm": "Are you sure you want to remove this wallet from your device?",
-      "create_text_code": "Generate TextCode to export",
+      "create_text_code": "Export by generating a TextCode",
       "scan_qr.title": "Export by scanning a QR-Code",
       "scan_qr.no_camera": "If to the contrary, the other device does not have a camera, ",
       "scan_qr.other_has_camera": "If the other device where you want to import the Wallet, has a camera, then you can just click on the Back button and select <span class=\"path\">Generate QR to export</span>",
@@ -459,7 +459,7 @@
     },
     "wallet_login_textcode": {
       "title": "Import Wallet from TextCode",
-      "description": "To generate a TextCode, open a logged in device and go to<br /><span class=\"path\">User Panel > Wallet > Generate TextCode to export</span>.",
+      "description": "To generate a TextCode, open a logged in device and go to<br /><span class=\"path\">User Panel > Wallet > Export by generating a TextCode</span>.",
       "import_btn": "Import with TextCode",
       "enter_here": "Enter your TextCode here below and click on Import button"
     },
diff --git a/ng-app/src/routes/WalletInfo.svelte b/ng-app/src/routes/WalletInfo.svelte
index f944e5e..08241ea 100644
--- a/ng-app/src/routes/WalletInfo.svelte
+++ b/ng-app/src/routes/WalletInfo.svelte
@@ -195,7 +195,7 @@
           <SidebarWrapper
               divClass="bg-gray-60 overflow-y-auto py-4 px-3 rounded dark:bg-gray-800"
           >
-            <SidebarGroup ulClass="space-y-2" role="menu">
+            <SidebarGroup ulClass="space-y-2" class="text-left" role="menu">
               <li>
                 <h2 class="text-xl mb-6">{$t("pages.wallet_info.title")}</h2>
               </li>
diff --git a/ng-app/src/store.ts b/ng-app/src/store.ts
index c3043fa..72cd530 100644
--- a/ng-app/src/store.ts
+++ b/ng-app/src/store.ts
@@ -111,6 +111,12 @@ export const toast = function(level, text) {
     });
 }
 
+export const reset_toasts = function() {
+    toasts.update((old)=>{
+        return [];
+    });
+}
+
 export const toast_error = (text) => {
     toast("error", text);
 }
@@ -377,13 +383,22 @@ export const digest_to_string = function(digest) {
     return encode(buffer.buffer);
 };
 
+export const sparql_query = async function(sparql:string, union:boolean) {
+    let session = get(active_session);
+    if (!session) {
+        throw new Error("no session");
+    }
+    let nuri = union ? undefined : "did:ng:"+get(cur_tab).branch.nuri;
+    return await ng.sparql_query(session.session_id, sparql, nuri);
+}
+
 export const sparql_update = async function(sparql:string) {
     let session = get(active_session);
     if (!session) {
         throw new Error("no session");
     }
     let nuri = "did:ng:"+get(cur_tab).branch.nuri;
-    await ng.sparql_update(session.session_id, nuri, sparql);
+    await ng.sparql_update(session.session_id, sparql, nuri);
 }
 
 export const branch_subscribe = function(nuri:string, in_tab:boolean) {
diff --git a/ng-app/src/styles.css b/ng-app/src/styles.css
index 95f2b59..d4b0f39 100644
--- a/ng-app/src/styles.css
+++ b/ng-app/src/styles.css
@@ -9,6 +9,11 @@
 // according to those terms.
 */
 
+td.hljs {
+    padding-left: 0 !important;
+    padding-right: 0 !important;
+}
+
 /** To format paths, like Settings > Wallet > Generate Wallet QR */
 .path {
     font-family: monospace;
diff --git a/ng-app/src/turtle.js b/ng-app/src/turtle.js
new file mode 100644
index 0000000..d623c21
--- /dev/null
+++ b/ng-app/src/turtle.js
@@ -0,0 +1,139 @@
+/*
+Language: Turtle
+Author: Redmer KRONEMEIJER <redmer.kronemeijer@rdmr.eu>
+Contributors: Mark ELLIS <mark.ellis@stardog.com>, Vladimir ALEXIEV <vladimir.alexiev@ontotext.com>
+*/
+
+
+function hljsDefineTurtle(hljs) {
+  // export default function (hljs) {
+  var KEYWORDS = {
+    keyword: "BASE|2 PREFIX|5 @base|10 @prefix|10",
+    literal: "true false",
+    built_in: "a",
+  };
+
+  var IRI_LITERAL = {
+    // https://www.w3.org/TR/turtle/#grammar-production-IRIREF
+    className: "literal",
+    relevance: 1, // XML tags look also like relative IRIs
+    begin: /</,
+    end: />/,
+    // illegal: /[^\x00-\x20"{}|^`\\]/, // TODO: https://www.w3.org/TR/turtle/#grammar-production-UCHAR
+  };
+
+  // https://www.w3.org/TR/turtle/#terminals
+  var PN_CHARS_BASE =
+    "A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u10000-\uEFFFF";
+  var PN_CHARS_U = PN_CHARS_BASE + "_";
+  var PN_CHARS = "-" + PN_CHARS_U + "0-9\u00B7\u0300-\u036F\u203F-\u2040";
+  var BLANK_NODE_LABEL =
+    "_:[" + PN_CHARS_U + "0-9]([" + PN_CHARS + ".]*[" + PN_CHARS + "])?";
+  var PN_PREFIX =
+    "[" + PN_CHARS_BASE + "]([" + PN_CHARS + ".]*[" + PN_CHARS + "])?";
+  var PERCENT = "%[0-9A-Fa-f][0-9A-Fa-f]";
+  var PN_LOCAL_ESC = "\\\\[_~.!$&'()*+,;=/?#@%-]";
+  var PLX = PERCENT + "|" + PN_LOCAL_ESC;
+  var PNAME_NS = "(" + PN_PREFIX + ")?:";
+  var PN_LOCAL =
+    "([" +
+    PN_CHARS_U +
+    ":0-9]|" +
+    PLX +
+    ")([" +
+    PN_CHARS +
+    ".:]|" +
+    PLX +
+    ")*([" +
+    PN_CHARS +
+    ":]|" +
+    PLX +
+    ")?";
+  var PNAME_LN = PNAME_NS + PN_LOCAL;
+  var PNAME_NS_or_LN = PNAME_NS + "(" + PN_LOCAL + ")?";
+
+  var PNAME = {
+    begin: PNAME_NS_or_LN,
+    relevance: 0,
+    className: "symbol",
+  };
+
+  var BLANK_NODE = {
+    begin: BLANK_NODE_LABEL,
+    relevance: 10,
+    className: "template-variable",
+  };
+
+  var LANGTAG = {
+    begin: /@[a-zA-Z]+([a-zA-Z0-9-]+)*/,
+    className: "type",
+    relevance: 0, // also catches objectivec keywords like: @protocol, @optional
+  };
+
+  var DATATYPE = {
+    begin: "\\^\\^" + PNAME_LN,
+    className: "type",
+    relevance: 10,
+  };
+
+  var TRIPLE_APOS_STRING = {
+    begin: /'''/,
+    end: /'''/,
+    className: "string",
+    relevance: 0,
+  };
+
+  var TRIPLE_QUOTE_STRING = {
+    begin: /"""/,
+    end: /"""/,
+    className: "string",
+    relevance: 0,
+  };
+
+  var APOS_STRING_LITERAL = JSON.parse(JSON.stringify(hljs.APOS_STRING_MODE));
+  APOS_STRING_LITERAL.relevance = 0;
+
+  var QUOTE_STRING_LITERAL = JSON.parse(JSON.stringify(hljs.QUOTE_STRING_MODE));
+  QUOTE_STRING_LITERAL.relevance = 0;
+
+  return {
+    name: "Turtle",
+    case_insensitive: true, // however `true` and `@prefix` are oblig. cased thus
+    keywords: KEYWORDS,
+    aliases: ["turtle", "ttl", "n3"],
+    contains: [
+      LANGTAG,
+      DATATYPE,
+      IRI_LITERAL,
+      BLANK_NODE,
+      PNAME,
+      TRIPLE_APOS_STRING,
+      TRIPLE_QUOTE_STRING, // order matters
+      APOS_STRING_LITERAL,
+      QUOTE_STRING_LITERAL,
+      hljs.C_NUMBER_MODE,
+      hljs.HASH_COMMENT_MODE,
+    ],
+    exports: {
+      LANGTAG: LANGTAG,
+      DATATYPE: DATATYPE,
+      IRI_LITERAL: IRI_LITERAL,
+      BLANK_NODE: BLANK_NODE,
+      PNAME: PNAME,
+      TRIPLE_APOS_STRING: TRIPLE_APOS_STRING,
+      TRIPLE_QUOTE_STRING: TRIPLE_QUOTE_STRING,
+      APOS_STRING_LITERAL: APOS_STRING_LITERAL,
+      QUOTE_STRING_LITERAL: QUOTE_STRING_LITERAL,
+      NUMBER: hljs.C_NUMBER_MODE,
+      KEYWORDS: KEYWORDS,
+    },
+  };
+}
+
+// module.exports = function (hljs) {
+//   hljs.registerLanguage("turtle", hljsDefineTurtle);
+// };
+
+// module.exports.definer = hljsDefineTurtle;
+
+export const definer = hljsDefineTurtle;
diff --git a/ng-app/src/zeras.ts b/ng-app/src/zeras.ts
index f837085..d4001a4 100644
--- a/ng-app/src/zeras.ts
+++ b/ng-app/src/zeras.ts
@@ -85,12 +85,12 @@ export const official_apps = {
         "ng:b": "TripleViewer",
         "ng:o": ["data:graph"],
     },
-    "n:g:z:sparql_query:yasgui": {
+    "n:g:z:sparql_query": {
         "ng:n": "SPARQL Query",
         "ng:a": "View, edit and invoke a 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:g": "n:g:z:sparql_query",
         "ng:b": "SparqlQueryEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
         "ng:o": ["data:graph"],
         "ng:w": ["query:sparql"],
@@ -115,12 +115,12 @@ export const official_apps = {
         "ng:o": ["data:graph"],
         "ng:w": ["query:graphql"],
     },
-    "n:g:z:sparql_update:yasgui": {
+    "n:g:z:sparql_update": {
         "ng:n": "SPARQL Update",
         "ng:a": "View, edit and invoke a 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:g": "n:g:z:sparql_update",
         "ng:b": "SparqlUpdateEditor", // YASGUI of Zazuko https://github.com/zazuko/trifid/tree/main/packages/yasgui
         "ng:o": [],
         "ng:w": ["query:sparql_update","data:graph"],
diff --git a/ng-sdk-js/src/lib.rs b/ng-sdk-js/src/lib.rs
index 2aa3cdb..273ea5e 100644
--- a/ng-sdk-js/src/lib.rs
+++ b/ng-sdk-js/src/lib.rs
@@ -259,16 +259,26 @@ pub async fn session_headless_stop(session_id: JsValue, force_close: bool) -> Re
 
     Ok(())
 }
-
+/*let app_response = nextgraph::verifier::prepare_app_response_for_js(app_response)?; */
 #[cfg(wasmpack_target = "nodejs")]
 #[wasm_bindgen]
-pub async fn sparql_query(session_id: JsValue, sparql: String) -> Result<JsValue, JsValue> {
+pub async fn sparql_query(
+    session_id: JsValue,
+    sparql: String,
+    nuri: JsValue,
+) -> Result<JsValue, JsValue> {
     let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
         .map_err(|_| "Invalid session_id".to_string())?;
+    let nuri = if nuri.is_string() {
+        NuriV0::new_from(&nuri.as_string().unwrap())
+            .map_err(|_| "Deserialization error of Nuri".to_string())?
+    } else {
+        NuriV0::new_entire_user_site()
+    };
 
     let request = AppRequest::V0(AppRequestV0 {
         command: AppRequestCommandV0::new_read_query(),
-        nuri: NuriV0::new_entire_user_site(),
+        nuri,
         payload: Some(AppRequestPayload::new_sparql_query(sparql)),
         session_id,
     });
@@ -305,8 +315,8 @@ pub async fn sparql_query(session_id: JsValue, sparql: String) -> Result<JsValue
 #[wasm_bindgen]
 pub async fn sparql_update(
     session_id: JsValue,
-    nuri: String,
     sparql: String,
+    nuri: String,
 ) -> Result<(), String> {
     let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
         .map_err(|_| "Invalid session_id".to_string())?;
@@ -329,6 +339,58 @@ pub async fn sparql_update(
     }
 }
 
+#[cfg(not(wasmpack_target = "nodejs"))]
+#[wasm_bindgen]
+pub async fn sparql_query(
+    session_id: JsValue,
+    sparql: String,
+    nuri: JsValue,
+) -> Result<JsValue, JsValue> {
+    let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(session_id)
+        .map_err(|_| "Invalid session_id".to_string())?;
+
+    let nuri = if nuri.is_string() {
+        NuriV0::new_from(&nuri.as_string().unwrap())
+            .map_err(|_| "Deserialization error of Nuri".to_string())?
+    } else {
+        NuriV0::new_entire_user_site()
+    };
+    let request = AppRequest::V0(AppRequestV0 {
+        command: AppRequestCommandV0::new_read_query(),
+        nuri,
+        payload: Some(AppRequestPayload::new_sparql_query(sparql)),
+        session_id,
+    });
+
+    let response = nextgraph::local_broker::app_request(request)
+        .await
+        .map_err(|e: NgError| e.to_string())?;
+
+    let AppResponse::V0(res) = response;
+    match res {
+        AppResponseV0::False => return Ok(JsValue::FALSE),
+        AppResponseV0::True => return Ok(JsValue::TRUE),
+        AppResponseV0::Graph(graph) => {
+            let triples: Vec<Triple> = serde_bare::from_slice(&graph)
+                .map_err(|_| "Deserialization error of Vec<Triple>".to_string())?;
+
+            Ok(JsValue::from(
+                triples
+                    .into_iter()
+                    .map(|x| JsValue::from_str(&x.to_string()))
+                    .collect::<Array>(),
+            ))
+        }
+        AppResponseV0::QueryResult(buf) => {
+            let string = String::from_utf8(buf)
+                .map_err(|_| "Deserialization error of JSON QueryResult String".to_string())?;
+            js_sys::JSON::parse(&string)
+        }
+        AppResponseV0::Error(e) => Err(e.to_string().into()),
+        _ => Err("invalid AppResponse".to_string().into()),
+    }
+}
+
 #[cfg(wasmpack_target = "nodejs")]
 #[wasm_bindgen]
 pub async fn rdf_dump(session_id: JsValue) -> Result<String, String> {
diff --git a/ng-verifier/src/lib.rs b/ng-verifier/src/lib.rs
index fcb8564..1dbe491 100644
--- a/ng-verifier/src/lib.rs
+++ b/ng-verifier/src/lib.rs
@@ -17,7 +17,7 @@ mod rocksdb_user_storage;
 use ng_net::app_protocol::*;
 use ng_oxigraph::oxrdf::Triple;
 
-fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> {
+pub fn triples_ser_to_json_string(ser: &Vec<u8>) -> Result<String, String> {
     let triples: Vec<Triple> = serde_bare::from_slice(ser)
         .map_err(|_| "Deserialization error of Vec<Triple>".to_string())?;
 
@@ -26,8 +26,12 @@ fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> {
         triples_json.push(serde_json::Value::String(insert.to_string()));
     }
     let triples_json = serde_json::Value::Array(triples_json);
-    let json = serde_json::to_string(&triples_json)
-        .map_err(|_| "Cannot serialize Vec<Triple> to JSON".to_string())?;
+    serde_json::to_string(&triples_json)
+        .map_err(|_| "Cannot serialize Vec<Triple> to JSON".to_string())
+}
+
+fn triples_ser_to_json_ser(ser: &Vec<u8>) -> Result<Vec<u8>, String> {
+    let json = triples_ser_to_json_string(ser)?;
     Ok(json.as_bytes().to_vec())
 }
 
diff --git a/ng-verifier/src/request_processor.rs b/ng-verifier/src/request_processor.rs
index 87035af..56bbade 100644
--- a/ng-verifier/src/request_processor.rs
+++ b/ng-verifier/src/request_processor.rs
@@ -169,6 +169,7 @@ impl Verifier {
                 if update {
                     return Err(NgError::InvalidTarget);
                 } else {
+                    //log_info!("QUERYING UNION GRAPH");
                     return Ok(None);
                 }
             }
@@ -248,7 +249,7 @@ impl Verifier {
                         query,
                     )))) = payload
                     {
-                        log_debug!("query={}", query);
+                        //log_debug!("query={}", query);
                         let store = self.graph_dataset.as_ref().unwrap();
                         let parsed = Query::parse(&query, None);
                         if parsed.is_err() {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index af5ffa8..1c0e313 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -30,6 +30,7 @@ importers:
       dayjs: ^1.11.10
       flowbite: ^1.6.5
       flowbite-svelte: ^0.43.3
+      highlight.js: ^11.10.0
       html5-qrcode: ^2.3.8
       internal-ip: ^7.0.0
       ng-sdk-js: workspace:^0.1.0-preview.1
@@ -42,6 +43,7 @@ importers:
       svelte-check: ^3.0.0
       svelte-codemirror-editor: ^1.4.0
       svelte-heros-v2: ^0.10.12
+      svelte-highlight: ^7.7.0
       svelte-i18n: ^4.0.0
       svelte-inview: ^4.0.2
       svelte-preprocess: ^5.0.3
@@ -83,6 +85,7 @@ importers:
       autoprefixer: 10.4.14_postcss@8.4.24
       cross-env: 7.0.3
       dayjs: 1.11.10
+      highlight.js: 11.10.0
       internal-ip: 7.0.0
       node-gzip: 1.1.2
       postcss: 8.4.24
@@ -91,6 +94,7 @@ importers:
       svelte: 3.59.1
       svelte-check: 3.4.3_sxhny56dlbcmwov4vk7qwrzshi
       svelte-heros-v2: 0.10.12_svelte@3.59.1
+      svelte-highlight: 7.7.0
       svelte-preprocess: 5.0.4_vmz4xia4c7tzh4ii3qac2x3tom
       svelte-time: 0.8.0
       tailwindcss: 3.3.2
@@ -1604,6 +1608,11 @@ packages:
       function-bind: 1.1.1
     dev: true
 
+  /highlight.js/11.10.0:
+    resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==}
+    engines: {node: '>=12.0.0'}
+    dev: true
+
   /html5-qrcode/2.3.8:
     resolution: {integrity: sha512-jsr4vafJhwoLVEDW3n1KvPnCCXWaQfRng0/EEYk1vNcQGcG/htAdhJX0be8YyqMoSz7+hZvOZSTAepsabiuhiQ==}
     dev: false
@@ -2263,6 +2272,12 @@ packages:
       svelte: 3.59.1
     dev: true
 
+  /svelte-highlight/7.7.0:
+    resolution: {integrity: sha512-umBiTz3fLbbNCA+wGlRhJOb54iC6ap8S/dxjauQ+g6a8oFGTOGQeOP2rJVoh/K1ssF7IjP4P0T3Yuiu+vtaG5Q==}
+    dependencies:
+      highlight.js: 11.10.0
+    dev: true
+
   /svelte-hmr/0.15.2_svelte@3.59.1:
     resolution: {integrity: sha512-q/bAruCvFLwvNbeE1x3n37TYFb3mTBJ6TrCq6p2CoFbSTNhDE9oAtEfpy+wmc9So8AG0Tja+X0/mJzX9tSfvIg==}
     engines: {node: ^12.20 || ^14.13.1 || >= 16}