Browse Source

drag spec

Maxim Sokhatsky 11 years ago
parent
commit
f87a532cb5

+ 166 - 0
apps/web/priv/static/doc/bert.js

@@ -0,0 +1,166 @@
+// Micro BERT encoder/decoder
+// Copyright (c) Maxim Sokhatsky (@5HT)
+
+function atom(o) { return { type: "Atom", value: o, toString: function() { return this.value; } }; };
+function bin(o) { return { type: "Binary", value: o, toString: function() { return "<<\'"+this.value+"'>>"; } }; };
+function tuple() {
+    return { type: "Tuple", value: arguments, toString: function() { var s = ""; 
+        for (var i=0;i<this.value.length;i++) { if (s!=="") s+=","; s+=this.value[i]; }
+        return "{" + s + "}"; } }; };
+function dec(S) { return decode(ltoa(new Uint8Array(S))); };
+function enc(s) {
+    var ori = encode(s), buf = new Uint8Array(new ArrayBuffer(ori.length));
+    for (var i=0; i < buf.length; i++) { buf[i] = ori.charCodeAt(i); }
+    return new Blob([buf.buffer]); };
+
+BERT = itoa(131);
+SATOM = itoa(115);
+ATOM = itoa(100);
+BINARY = itoa(109);
+SINT = itoa(97);
+INT = itoa(98);
+FLOAT = itoa(99);
+STR = itoa(107);
+LIST = itoa(108);
+SBIG = itoa(110);
+LBIG = itoa(111);
+TUPLE = itoa(104);
+LTUPLE = itoa(105);
+NIL = itoa(106);
+ZERO = itoa(0);
+
+function itoa(x) { return String.fromCharCode(x); }
+function ltoa(a) { for (var i = 0,s=""; i < a.length; i++) s += itoa(a[i]); return s; };
+function itol(Int, Length) {
+    var isNegative, OriginalInt, i, Rem, s = "";
+    isNegative = (Int < 0);
+    if (isNegative) { Int = Int * (0 - 1); }
+    OriginalInt = Int;
+    for (i = 0; i < Length; i++) { 
+        Rem = Int % 256;
+        if (isNegative) { Rem = 255 - Rem; }
+        s = String.fromCharCode(Rem) + s;
+        Int = Math.floor(Int / 256);
+    }
+    if (Int > 0) { throw ("BERT: Range: " + OriginalInt); }
+    return s; };
+function ltoi(S, Length) {
+    var isNegative, i, n, Num = 0;
+    isNegative = (S.charCodeAt(0) > 128);
+    for (i = 0; i < Length; i++) {
+        n = S.charCodeAt(i);
+        if (isNegative) { n = 255 - n; }
+        if (Num === 0) { Num = n; }
+        else { Num = Num * 256 + n; }
+    }
+    if (isNegative) { Num = Num * (0 - 1); }
+    return Num; };
+function ltobi(S, Count) {
+    var isNegative, i, n, Num = 0;
+    isNegative = (S.charCodeAt(0) === 1);
+    S = S.substring(1);
+    for (i = Count - 1; i >= 0; i--) {
+        n = S.charCodeAt(i);
+        if (Num === 0) { Num = n; } else { Num = Num * 256 + n; } }
+    if (isNegative) { return Num * -1; }
+    return Num; };
+
+function encode(o) { return BERT + en_inner(o); };
+function en_inner(Obj) { if(Obj === undefined) return NIL; var func = 'en_' + typeof(Obj); return eval(func)(Obj); };
+function en_string(Obj) { return STR + itol(Obj.length, 2) + Obj; };
+function en_boolean(Obj) { if (Obj) return en_inner(atom("true")); else return en_inner(atom("false")); };
+function en_number(Obj) { var s, isi = (Obj % 1 === 0); if (!isi) { return en_float(Obj); }
+    if (isi && Obj >= 0 && Obj < 256) { return SINT + itol(Obj, 1); }
+    return INT + itol(Obj, 4); };
+function en_float(Obj) { var s = Obj.toExponential(); while (s.length < 31) { s += ZERO; } return FLOAT + s; };
+function en_object(Obj) {
+    if (Obj.type === "Atom") return en_atom(Obj);
+    if (Obj.type === "Binary") return en_bin(Obj);
+    if (Obj.type === "Tuple") return en_tuple(Obj);
+    if (Obj.constructor.toString().indexOf("Array") !== -1) return en_array(Obj);
+    return en_associative_array(Obj); };
+function en_atom(Obj) { return ATOM + itol(Obj.value.length, 2) + Obj.value; };
+function en_bin(Obj) { return BINARY + itol(Obj.value.length, 4) + Obj.value; };
+function en_tuple(Obj) {
+    var i, s = "";
+    if (Obj.value.length < 256) { s += TUPLE + itol(Obj.value.length, 1); }
+    else { s += LTUPLE + itol(Obj.value.length, 4); }
+    for (i = 0; i < Obj.value.length; i++) { s += en_inner(Obj.value[i]); }
+    return s; };
+function en_array(Obj) {
+    var i, s = LIST + itol(Obj.length, 4);
+    for (i = 0; i < Obj.length; i++) { s += en_inner(Obj[i]); }
+    s += NIL;
+    return s; };
+function en_associative_array(Obj) {
+    var key, Arr = [];
+    for (key in Obj) { if (Obj.hasOwnProperty(key)) { Arr.push(tuple(atom(key), Obj[key])); } }
+    return en_array(Arr); };
+
+function decode(S) {
+    if (S[0] !== BERT) { throw ("Not a valid BERT."); }
+    var Obj = de_inner(S.substring(1));
+    if (Obj.rest !== "") { throw ("Invalid BERT."); }
+    return Obj.value; };
+function de_inner(S) {
+    var Type = S[0];
+    S = S.substring(1);
+    switch (Type) {
+        case SATOM: de_atom(S, 1);
+        case ATOM: return de_atom(S, 2);
+        case BINARY: return de_bin(S);
+        case SINT: return de_integer(S, 1);
+        case INT: return de_integer(S, 4);
+        case FLOAT: return de_float(S);
+        case SBIG: return de_big(S,1);
+        case LBIG: return de_big(S,4);
+        case STR: return de_string(S);
+        case LIST: return de_list(S);
+        case TUPLE: return de_tuple(S, 1);
+        case NIL: return de_nil(S);
+        default: throw ("BERT: " + S.charCodeAt(0)); } };
+function de_atom(S, Count) {
+    var Size, Value;
+    Size = ltoi(S, Count);
+    S = S.substring(Count);
+    Value = S.substring(0, Size);
+    if (Value === "true") { Value = true; }
+    else if (Value === "false") { Value = false; }
+    return { value: atom(Value), rest:  S.substring(Size) }; };
+function de_bin(S) {
+    var Size = ltoi(S, 4);
+    S = S.substring(4);
+    return { value: bin(S.substring(0, Size)), rest: S.substring(Size) }; };
+function de_big(S, Count) {
+    var Size, Value;
+    Size = ltoi(S, Count);
+    S = S.substring(Count);
+    Value = ltobi(S, Size);
+    return { value : Value, rest: S.substring(Size + 1) }; };
+function de_integer(S, Count) {
+    var Value = ltoi(S, Count);
+    S = S.substring(Count);
+    return { value: Value, rest: S }; };
+function de_float(S) {
+    var Size = 31;
+    return { value: parseFloat(S.substring(0, Size)), rest: S.substring(Size) }; };
+function de_string(S) {
+    var Size = ltoi(S, 2);
+    S = S.substring(2);
+    return { value: S.substring(0, Size), rest: S.substring(Size) }; };
+function de_list(S) {
+    var Size, i, El, LastChar, Arr = [];
+    Size = ltoi(S, 4);
+    S = S.substring(4);
+    for (i = 0; i < Size; i++) { El = de_inner(S); Arr.push(El.value); S = El.rest; }
+    LastChar = S[0];
+    if (LastChar !== NIL) { throw ("BERT: Wrong NIL."); }
+    S = S.substring(1);
+    return { value: Arr, rest: S }; };
+function de_tuple(S, Count) {
+    var Size, i, El, Arr = [];
+    Size = ltoi(S, Count);
+    S = S.substring(Count);
+    for (i = 0; i < Size; i++) { El = de_inner(S); Arr.push(El.value); S = El.rest; }
+    return { value: tuple(Arr), rest: S }; };
+function de_nil(S) { return { value: [], rest: S }; };

+ 164 - 0
apps/web/priv/static/doc/bullet.js

@@ -0,0 +1,164 @@
+function bullet(url) {
+
+    var CONNECTING = 0;
+    var OPEN = 1;
+    var CLOSING = 2;
+    var CLOSED = 3;
+
+    var transports = {
+
+        websocket: function() {
+            var transport = null;
+            if (window.WebSocket) { transport = window.WebSocket; }
+            if (window.MozWebSocket) { transport = window.MozWebSocket; }
+            if (transport) { return {'heart': true, 'transport': transport}; }
+            return null;
+        },
+
+        xhrPolling: function() {
+            var timeout;
+            var xhr;
+
+            nextPoll();
+
+            var fake = {
+                readyState: CONNECTING,
+
+                receive: function(data) {
+                    if (fake.readyState == CONNECTING) { fake.readyState = OPEN; fake.onopen(fake); }
+                    if (data.length != 0) { fake.onmessage({'data': data }); }
+                    if (fake.readyState == OPEN) { nextPoll(); }
+                },
+
+                send: function(data) {
+                    if (this.readyState != CONNECTING && this.readyState != OPEN) return false;
+                    var fakeurl = url.replace('ws:', 'http:').replace('wss:', 'https:');
+                    var request = new XMLHttpRequest();
+                    request.open('POST',fakeurl,true);
+                    request.setRequestHeader('Content-Type',
+                        'application/x-www-form-urlencoded; charset=utf-8');
+                    request.setRequestHeader('X-Socket-Transport','xhrPolling');
+                    request.onload = function() { fake.receive(request.response); }
+                    request.send(data);
+                    return true;
+                },
+                close: function(){
+                    this.readyState = CLOSED;
+                    xhr.abort();
+                    clearTimeout(timeout);
+                    fake.onclose();
+                },
+                onopen: function(){},
+                onmessage: function(){},
+                onerror: function(){},
+                onclose: function(){}
+            };
+
+            function poll(pooling){
+                var fakeurl = url.replace('ws:', 'http:').replace('wss:', 'https:');
+                var request = new XMLHttpRequest();
+                request.open('GET',fakeurl,true);
+                request.setRequestHeader('Content-Type',
+                    'application/x-www-form-urlencoded; charset=utf-8');
+                request.setRequestHeader('X-Socket-Transport','xhrPolling');
+                request.onload = function() { fake.receive(request.response); }
+                request.onerror = function() { fake.onerror(); }
+                request.send({});
+            }
+
+            function nextPoll() { timeout = setTimeout(function(){poll();}, 1000); }
+
+
+            return {'heart': false, 'transport': function(){ return fake; fake.nextPoll(); }};
+        }
+    };
+
+    var tn = 0;
+    function next() {
+        var c = 0;
+
+        for (var f in transports) {
+            if (tn == c) {
+                var t = transports[f]();
+                if (t) { var ret = new t.transport(url); ret.heart = t.heart; return ret; }
+                tn++;
+            }
+            c++;
+        }
+        return false;
+    }
+
+    var stream = new function() {
+        var isClosed = true;
+        var readyState = CLOSED;
+        var heartbeat;
+        var delay = 80;
+        var delayDefault = 80;
+        var delayMax = 10000;
+
+        var transport;
+        function init() {
+
+            isClosed = false;
+            readyState = CONNECTING;
+            transport = next();
+
+            if (!transport) {
+                delay = delayDefault;
+                tn = 0;
+                stream.ondisconnect();
+                setTimeout(function(){init();}, delayMax);
+                return false;
+            }
+
+            transport.onopen = function() {
+                delay = delayDefault;
+
+                if (transport.heart) { 
+                    heartbeat = setInterval(function(){stream.onheartbeat();}, 4000);
+                }
+
+                if (readyState != OPEN) { readyState = OPEN; stream.onopen(); }
+            };
+
+            transport.onclose = function() {
+                if (isClosed) { return; }
+
+                transport = null;
+                clearInterval(heartbeat);
+
+                if (readyState == CLOSING){
+                    readyState = CLOSED;
+                    stream.onclose();
+                } else {
+                    if (readyState == CONNECTING) tn++;
+                    delay *= 2;
+                    if (delay > delayMax) { delay = delayMax; }
+                    isClosed = true;
+                    setTimeout(function() { init(); }, delay);
+                }
+            };
+            transport.onerror = transport.onclose;
+            transport.onmessage = function(e){
+            stream.onmessage(e);
+            };
+        }
+
+        init();
+
+        this.onopen = function(){};     this.oninit = function(){};
+        this.onmessage = function(){};  this.ondisconnect = function(){ initialized = false; };
+        this.onclose = function(){};    this.onheartbeat = function(){ return this.send('PING'); };
+
+        this.setURL = function(newURL) { url = newURL; };
+        this.send = function(data){
+            if (transport) return transport.send(data); else return false;
+        };
+        this.close = function(){
+            readyState = CLOSING;
+            if (transport) transport.close();
+        };
+    };
+
+    return stream;
+}

+ 4 - 1
apps/web/priv/static/doc/contents.htm

@@ -13,17 +13,20 @@ Client
 <a target="_parent" href="svg_mock.htm">SVG Mock</a><br>
 <a target="_parent" href="campaigns_mock.htm">Campaigns SVG Mock</a><br>
 <a target="_parent" href="svg.htm">SVG App Requirements</a><br>
+<a target="_parent" href="drag.htm">Drag Spec</a><br>
 </blockquote>
 
 Server<br>
 <blockquote>
 <a target="_parent" href="game_server.htm">Game Server</a><br>
-<a target="_parent" href="kvs_schema.htm">Database</a><br>
 </blockquote>
 
 Schedule<br>
 <blockquote>
 <a target="_parent" href="plans/april2014.htm">April 2014</a><br>
+<a target="_parent" href="plans/april2014.htm">May 2014</a><br>
+<a target="_parent" href="plans/april2014.htm">June 2014</a><br>
+<a target="_parent" href="plans/april2014.htm">July 2014</a><br>
 </blockquote>
 
 </body>

+ 61 - 0
apps/web/priv/static/doc/drag.htm

@@ -0,0 +1,61 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<link href="synrc.css" type="text/css" rel="stylesheet">
+</head>
+<body>
+
+<div class="threecol">
+
+<div class="left">
+<div class="hints"></div>
+<div class="main">
+
+<h1><a name="chapter2">Card Dragging</a></h1>
+
+<h2><a name="p1.1">1. Устойчивые Карты</a></h2>
+
+<p>Когда мы ведем карту над доской, она встряхивает другие карты,
+но как только ведомая карта уходит за пределы группы, встряхнутые
+карты возвращаются на свое место.</p>
+
+<img src="images/drag4.png">
+
+<h2><a name="p1.2">2. Зона захвата карты</a></h2>
+
+<p>Сейчас зона захвата определяется по курсору. Это не совсем удобно.
+Напрмер для зоны сбрасывания достаточно что бы 25% накрывало зону сбрасываныя.
+То же касается и случая когда карта находится посредине между четырех зон на доске.</P>
+
+<img src="images/drag1.png">
+<img src="images/drag2.png">
+
+<h2><a name="p1.1">3. Карты не могут накрывать друг друга</a></h2>
+
+<p>Карты не могут накрывать друг друга. Это ошибочное поведение.</p>
+
+
+<h2><a name="p1.1">4. Карта должна легко ставиться между картами</a></h2>
+
+<p>Сейчас, чтобы поставить карту между двумя картами нужно
+сделать минимум два движения. Так быть не должно. Не надо так.</p>
+
+<h2><a name="p1.1">5. Двигать группы вправо и влево</a></h2>
+
+<p>Мы должны иметь возможность двигать группу картой в направление движения.
+Наприме если мы хохим подвинуть группу влево (вправо), то мы должны
+справа (слева) коснуться ее ведомой картой. Неважно откуда эта карта взялась.</p>
+
+<img src="images/drag3.png">
+<img src="images/drag5.png">
+
+</div>
+
+<div class="contents">
+<iframe src="contents.htm" frameborder=0 width=340 height=2190></iframe>
+</div>
+
+</body>
+</html>
+
+

BIN
apps/web/priv/static/doc/images/drag1.png


BIN
apps/web/priv/static/doc/images/drag2.png


BIN
apps/web/priv/static/doc/images/drag3.png


BIN
apps/web/priv/static/doc/images/drag4.png


BIN
apps/web/priv/static/doc/images/drag5.png


+ 155 - 0
apps/web/priv/static/doc/n2o.js

@@ -0,0 +1,155 @@
+var msg = 0;
+var ws;
+var utf8 = {};
+
+//WebSocket = undefined; // test XHR fallback
+
+function addStatus(text){
+    var date = new Date();
+    if (document.getElementById('n2ostatus')) {
+        document.getElementById('n2ostatus').innerHTML =
+            document.getElementById('n2ostatus').innerHTML + "E> " + text + "<br/>";
+    }
+}
+
+utf8.toByteArray = function(str) {
+    var byteArray = [];
+    if (str !== undefined && str !== null)
+    for (var i = 0; i < str.length; i++)
+        if (str.charCodeAt(i) <= 0x7F)
+            byteArray.push(str.charCodeAt(i));
+        else {
+            var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
+            for (var j = 0; j < h.length; j++)
+                byteArray.push(parseInt(h[j], 16));
+        }
+    return byteArray;
+};
+
+function byteArray8toString (byteArray, separator) {
+    if (typeof byteArray == 'undefined' || byteArray.byteLength == 0) { return "" };
+    separator = typeof separator !== 'undefined' ? separator : ',';
+    var dataView = new DataView(byteArray);
+    var s = dataView.getUint8(0).toString();
+    for (var i = 1; i < byteArray.byteLength; i++)
+        s = s + separator + dataView.getUint8(i).toString();
+    return s;
+}
+
+function WebSocketsInit(){
+    if ("MozWebSocket" in window) { WebSocket = MozWebSocket; }
+    if ("WebSocket" in window) {
+        ws = new bullet("ws://"+
+          (null == transition.host ? window.location.hostname : transition.host)
+               + ":"+ (null == transition.port ? window.location.port : transition.port)
+             + "/ws" + window.location.pathname + window.location.search);
+        initialized = false;
+        ws.onmessage = function (evt) {
+
+            try { // try to parse JSON envelop {eval:"",data:""}
+
+                msg = JSON.parse(evt.data);
+
+                if (typeof handle_web_socket == 'function' && msg.data) { // Data
+                    // addStatus("Received: " + bert.decodebuf(msg.data));
+                    handle_web_socket(msg.data);
+                }
+
+                if (msg.eval) { // Eval
+                    // addStatus("Evaluate: " + msg.eval);
+                    try{eval(msg.eval);}catch(e){console.log(e); console.log(msg.eval);};
+                }
+
+            } catch (ex) { // try to parse known binary formats
+                
+                var HEAD_SIZE = 36;
+
+                // console.log("JSON parsing failed: " + ex);
+                // console.log("MessageEvent: ");
+                // console.log(evt.data);
+                
+                var header_reader = new FileReader();
+                header_reader.addEventListener("loadend", function() {
+
+                    if(header_reader.result.byteLength > 0) {
+                        var header_view = new DataView(header_reader.result);
+                        var head_char = header_view.getUint8(0);
+                    
+                        try { // BERT encoding
+
+                            if (head_char !== 131) { throw ("Not a valid BERT header."); }
+                            else {
+                                var bert_reader = new FileReader();
+                                bert_reader.addEventListener("loadend", function() {
+                                    var erlang = dec(bert_reader.result);
+                                    if (typeof handle_web_socket == 'function')
+                                        handle_web_socket(erlang);
+                                    else console.log("Raw BERT Received: " + erlang);
+                                });
+                                bert_reader.readAsArrayBuffer(evt.data);
+                            }
+
+                        } catch (x) { // Binaries
+
+                            if (head_char == 132 && header_reader.result.byteLength == HEAD_SIZE) {
+                                // Headered Binaries
+                                // [132, HEADER, META, DATA]
+                                var id = header_view.getUint32(1);
+                                var type = header_view.getUint8(5);
+                                var app = header_view.getUint8(6);
+                                var version = header_view.getUint8(7);
+                                var from = header_view.getUint32(8);
+                                var to = header_view.getUint32(12);
+                                var user1 = header_view.getFloat64(16);
+                                var user2 = header_view.getFloat64(24);
+                                var data_offset = HEAD_SIZE + header_view.getUint32(32);
+                                var meta_reader = new FileReader();
+                                meta_reader.addEventListener("loadend", function() {
+                                    if (typeof handle_web_socket_blob_with_header == 'function')
+                                        handle_web_socket_blob_with_header(id, type, app, version, from, to, user1, user2,
+                                            meta_reader.result, evt.data.slice(data_offset));
+                                    else {
+                                        console.log("Raw Binary With Header Received: Header [" + byteArray8toString(header_reader.result)
+                                            + "] Meta [" + byteArray8toString(meta_reader.result)
+                                            + "] Data lehgth: " + (evt.data.size - data_offset));
+                                        console.log("Header fields { id: " + id + ", type: " + type + ", app: " + app + ", version: " + version
+                                            + ", from: " + from + ", to: " + to + ", user1: " + user1 + ", user2: " + user2 + " }");
+                                    }
+                                });
+                                meta_reader.readAsArrayBuffer(evt.data.slice(HEAD_SIZE, data_offset));
+                            }
+                            else { // Unknown Binaries
+                            
+                                if (typeof handle_web_socket_blob == 'function')
+                                    handle_web_socket_blob(evt.data);
+                                else {
+                                    var reader = new FileReader();
+                                    reader.addEventListener("loadend", function() {
+                                        if (reader.result.byteLength > 0) {
+                                            var dataView = new DataView(reader.result);
+                                            var s = dataView.getUint8(0).toString();
+                                            for (var i=1;i<reader.result.byteLength;i++)
+                                                s = s + "," + dataView.getUint8(i).toString();
+                                            console.log("Unknown Raw Binary Received: [" + s + "]");
+                                        }
+                                    });
+                                    reader.readAsArrayBuffer(evt.data);
+                                }
+                            }
+                        }
+                    }
+                });
+                header_reader.readAsArrayBuffer(evt.data.slice(0, HEAD_SIZE));
+
+            }
+
+        };
+        ws.onopen = function() { if (!initialized) { ws.send(['N2O', transition.pid]); initialized = true; } };
+        ws.onclose = function() { addStatus("websocket was closed"); };
+    } else {
+        addStatus("sorry, your browser does not support websockets.");
+    }
+}
+
+WebSocketsInit();
+

+ 6 - 8
apps/web/priv/static/doc/svg.htm

@@ -1,9 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <html>
 <head>
-    <meta charset="utf-8"/>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <link href="synrc.css" type="text/css" rel="stylesheet">
-<link href='http://fonts.googleapis.com/css?family=Exo+2:600' rel='stylesheet' type='text/css'>
 
 </head>
 <body>
@@ -254,20 +253,19 @@ XML елементами, як це є в WPF наприклад. Тут спр
 
 <p>Прототип тонкого клієнту на елементах HTML/CSS викладений тут:<p>
 
-<code><a href="http://srv5.kakaranet.com:8080">http://srv5.kakaranet.com:8080</a></code>
+<code><a href="http://localhost:8080/static/doc/svg_clean.htm">http://localhost:8080/static/doc/svg_clean.htm</a></code>
 
 </div>
 
 <div class="contents">
-<iframe src="contents.htm" frameborder=0 width=340 height=510></iframe>
+<iframe src="contents.htm?м=1" frameborder=0 width=340 height=510></iframe>
 </div>
 
 </div>
 
-
-<script src='../nitrogen/bullet.js' type='text/javascript' charset='utf-8'></script>
-<script src='../nitrogen/n2o.js' type='text/javascript' charset='utf-8'></script>
-<script src='../nitrogen/bert.js' type='text/javascript' charset='utf-8'></script>
+<script src='bullet.js' type='text/javascript' charset='utf-8'></script>
+<script src='n2o.js' type='text/javascript' charset='utf-8'></script>
+<script src='bert.js' type='text/javascript' charset='utf-8'></script>
 
 </body>
 </html>

+ 3 - 3
apps/web/priv/static/doc/svg_clean.htm

@@ -37,9 +37,9 @@
 <script src='kvs.js' type='text/javascript' charset='utf-8'></script>
 <script src='svg.js' type='text/javascript' charset='utf-8'></script>
 
-<script src='../nitrogen/bullet.js' type='text/javascript' charset='utf-8'></script>
-<script src='../nitrogen/n2o.js' type='text/javascript' charset='utf-8'></script>
-<script src='../nitrogen/bert.js' type='text/javascript' charset='utf-8'></script>
+<script src='bullet.js' type='text/javascript' charset='utf-8'></script>
+<script src='n2o.js' type='text/javascript' charset='utf-8'></script>
+<script src='bert.js' type='text/javascript' charset='utf-8'></script>
 
 </body>
 </html>

+ 1 - 1
apps/web/priv/static/doc/synrc.css

@@ -13,7 +13,7 @@
     H1          { font-size:30pt; color: blue; font-weight: bold; font-size:30pt; margin-top:20px; margin-bottom:10px; margin-right:6px; }
     H2          { font-size:20pt; color: darkblue; margin-top:20px; margin-bottom:10px; margin-right:6px; }
     H3          { font-size:18pt; margin-top:20px; margin-bottom:10px; margin-right:6px; } 
-    P           { display: none; visibility:hidden;font-size:14pt; margin-top: 0px; margin-bottom: 8px;  }
+    P           { font-size:14pt; margin-top: 0px; margin-bottom: 8px;  }
     H3 P        { font-size:16pt; margin-left: 70px; margin-top:20px; margin-bottom:10px; margin-right:6px; } 
     B           { font-size:14pt; background-color: lightblue; padding: 2px; }
     H2 B        { font-size:16pt; background-color: lightblue; padding: 5px; margin-top: 20px; margin-bottom: 20px;}