Commit b2e27561 authored by Gérard Meunier's avatar Gérard Meunier

Small detail improved

parent 8004d52b
......@@ -19,6 +19,8 @@ DEFINITION UtilBTree;
gt = 1;
TYPE
Bytes = POINTER TO ARRAY OF BYTE;
Factory = POINTER TO ABSTRACT RECORD
(fac: Factory) Create- (IN nF: ARRAY OF CHAR): BOOLEAN, NEW, ABSTRACT;
(fac: Factory) Open- (IN nF: ARRAY OF CHAR): File, NEW, ABSTRACT;
......@@ -39,8 +41,8 @@ DEFINITION UtilBTree;
(ref: File) Close-, NEW, ABSTRACT;
(ref: File) BytesToReal- (IN a: ARRAY OF BYTE; VAR pos: INTEGER): REAL, NEW, ABSTRACT;
(ref: File) BytesToSReal- (IN a: ARRAY OF BYTE; VAR pos: INTEGER): SHORTREAL, NEW, ABSTRACT;
(ref: File) RealToBytes- (r: REAL): POINTER TO ARRAY OF BYTE, NEW, ABSTRACT;
(ref: File) SRealToBytes- (r: SHORTREAL): POINTER TO ARRAY OF BYTE, NEW, ABSTRACT
(ref: File) RealToBytes- (r: REAL): Bytes, NEW, ABSTRACT;
(ref: File) SRealToBytes- (r: SHORTREAL): Bytes, NEW, ABSTRACT
END;
Database = POINTER TO LIMITED RECORD
......@@ -76,7 +78,8 @@ DEFINITION UtilBTree;
DataMan = POINTER TO LIMITED RECORD
(d: DataMan) ReadData (ptr: INTEGER): Data, NEW;
(d: DataMan) AllocateData (size: INTEGER): INTEGER, NEW;
(d: DataMan) AllocateData (data: Data): INTEGER, NEW;
(d: DataMan) WriteAllocateData (data: Data): INTEGER, NEW;
(d: DataMan) WriteData (ptr: INTEGER; data: Data), NEW;
(d: DataMan) EraseData (ptr: INTEGER), NEW
END;
......@@ -86,7 +89,7 @@ DEFINITION UtilBTree;
Index = POINTER TO LIMITED RECORD
(ind: Index) SearchIns (key: Data): BOOLEAN, NEW;
(ind: Index) Search (key: Data): BOOLEAN, NEW;
(ind: Index) Erase (key: Data), NEW;
(ind: Index) Erase (key: Data): BOOLEAN, NEW;
(ind: Index) NumberOfKeys (): INTEGER, NEW;
(ind: Index) ResetPos, NEW;
(ind: Index) GetCurrPos (): IndexPos, NEW;
......@@ -116,8 +119,10 @@ DEFINITION UtilBTree;
(VAR r: Reader) InByte (): BYTE, NEW;
(VAR r: Reader) InBytes (OUT b: ARRAY OF BYTE), NEW;
(VAR r: Reader) InSChar (): SHORTCHAR, NEW;
(VAR r: Reader) InSCharsLen (): INTEGER, NEW;
(VAR r: Reader) InSChars (OUT c: ARRAY OF SHORTCHAR), NEW;
(VAR r: Reader) InChar (): CHAR, NEW;
(VAR r: Reader) InCharsLen (): INTEGER, NEW;
(VAR r: Reader) InChars (OUT c: ARRAY OF CHAR), NEW;
(VAR r: Reader) InSInt (): SHORTINT, NEW;
(VAR r: Reader) InInt (): INTEGER, NEW;
......@@ -191,6 +196,9 @@ Result of a comparaison. Equal.
CONST gt
Result of a comparaison. Greater than.
TYPE Bytes
POINTER TO ARRAY OF BYTES.
TYPE Factory
ABSTRACT
Factory for files and databases.
......@@ -270,11 +278,11 @@ PROCEDURE (ref: File) BytesToSReal- (IN a: ARRAY OF BYTE; VAR pos: INTEGER): SHO
NEW, ABSTRACT
Read and return a shortreal from the array a at position pos; put pos at the position following the shortreal.
PROCEDURE (ref: File) RealToBytes- (r: REAL): POINTER TO ARRAY OF BYTE
PROCEDURE (ref: File) RealToBytes- (r: REAL): Bytes
NEW, ABSTRACT
Return a pointer to an array of byte coding for the real r.
PROCEDURE (ref: File) SRealToBytes- (r: SHORTREAL): POINTER TO ARRAY OF BYTE
PROCEDURE (ref: File) SRealToBytes- (r: SHORTREAL): Bytes
NEW, ABSTRACT
Return a pointer to an array of byte coding for the shortreal r.
......@@ -409,14 +417,23 @@ Pre
The database of d is open 20
ptr # bNil 21
PROCEDURE (d: DataMan) AllocateData (size: INTEGER): INTEGER
PROCEDURE (d: DataMan) AllocateData (data: Data): INTEGER
NEW
Allocate a cluster of size size (bytes), for the data managed by d, in its database, and returns its position. size must be the size of the production of the method Data.Write of the data managed by d.
Consider using WriteAllocateData instead.Allocate a cluster for data, managed by d, in the database of d, and return its position. Warning: AllocateData calls data.Write to find the size of data, be sure the value of data can be written and has its correct size.
Pre
The database of d is open 20
size > 0 21
PROCEDURE (d: DataMan) WriteAllocateData (data: Data): INTEGER
NEW
Allocate a cluster for data, managed by d, in the database of d, and write data into it; return the position of the allocated cluster.
Pre
The database of d is open 20
data # NIL 21
ptr # bNil 22
PROCEDURE (d: DataMan) WriteData (ptr: INTEGER; data: Data)
NEW
Write data, managed by d, at the position ptr in the database of d.
......@@ -458,9 +475,9 @@ Pre
ind is open 20
key # NIL 21
PROCEDURE (ind: Index) Erase (key: Data)
PROCEDURE (ind: Index) Erase (key: Data): BOOLEAN
NEW
Erase from index ind the key key. If the key key does not belong to the index, ind.Erase does nothing. If the current position of the index was on the erased key, it is reset.
Erase from index ind the key key. If key does not belong to the index, ind.Erase does nothing and returns FALSE, otherwise ir returns TRUE. If the current position of the index was on the erased key, it is reset.
Pre
ind is open 20
......@@ -616,6 +633,10 @@ Read a shortchar from the input stream.
Pre
r.pos + SIZE(SHORTCHAR) <= r.len 20
PROCEDURE (VAR r: Reader) InSCharsLen (): INTEGER
NEW
Return the length of the following array of shortchars to be read from the input stream. The length doesn't include the possible terminal 0X
PROCEDURE (VAR r: Reader) InSChars (OUT c: ARRAY OF SHORTCHAR)
NEW
Read an array of shortchars from the input stream. Reading stops when a 0X has been read, or when LEN(c) - 1 shortchars have been read, or when the end of the input stream has been reached. In any case the string returned in c is 0X terminated.
......@@ -627,6 +648,10 @@ Read a char from the input stream.
Pre
r.pos + SIZE(SHORTCHAR) <= r.len 20
PROCEDURE (VAR r: Reader) InCharsLen (): INTEGER
NEW
Return the length of the following array of chars to be read from the input stream. The length doesn't include the possible terminal 0X
PROCEDURE (VAR r: Reader) InChars (OUT c: ARRAY OF CHAR)
NEW
Read an array of chars from the input stream. Reading stops when a 0X has been read, or when LEN(c) - 1 chars have been read, or when the end of the input stream has been reached. In any case the string returned in c is 0X terminated.
......
......@@ -45,6 +45,8 @@ MODULE UtilBTree;
TYPE
Bytes* = POINTER TO ARRAY OF BYTE;
Factory* = POINTER TO ABSTRACT RECORD (* Factory for files and databases. *)
END;
......@@ -213,7 +215,7 @@ MODULE UtilBTree;
PageIFac = POINTER TO RECORD (DataFac) (* Factory of PageI *)
END;
Key = POINTER TO ARRAY OF BYTE; (* Key in indexes *)
Key = Bytes; (* Key in indexes *)
KeyCont = POINTER TO RECORD (Data) (* Key as Data *)
c: Key;
......@@ -255,7 +257,7 @@ MODULE UtilBTree;
len-, (* Length of the input stream of the reader. *)
pos-: INTEGER; (* Position of the reader in the input stream. *)
ref: File; (* Used for real <-> bytes translations. *)
s: POINTER TO ARRAY OF BYTE; (* Contain the input stream. *)
s: Bytes; (* Contain the input stream. *)
END;
Writer* = LIMITED RECORD (* Writer on a byte stream. *)
......@@ -398,13 +400,13 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
PROCEDURE (ref: File) BytesToSReal- (IN a: ARRAY OF BYTE; VAR pos: INTEGER): SHORTREAL, NEW, ABSTRACT;
(* Return a pointer to an array of byte coding for the real r. *)
PROCEDURE (ref: File) RealToBytes- (r: REAL): POINTER TO ARRAY OF BYTE, NEW, ABSTRACT;
PROCEDURE (ref: File) RealToBytes- (r: REAL): Bytes, NEW, ABSTRACT;
(* Return a pointer to an array of byte coding for the shortreal r. *)
PROCEDURE (ref: File) SRealToBytes- (r: SHORTREAL): POINTER TO ARRAY OF BYTE, NEW, ABSTRACT;
PROCEDURE (ref: File) SRealToBytes- (r: SHORTREAL): Bytes, NEW, ABSTRACT;
(* Initalize a reader *)
PROCEDURE (VAR r: Reader) InitReader (ref: File; a: POINTER TO ARRAY OF BYTE; pos: INTEGER), NEW;
PROCEDURE (VAR r: Reader) InitReader (ref: File; a: Bytes; pos: INTEGER), NEW;
BEGIN (*InitReader*)
r.ref := ref;
......@@ -481,6 +483,30 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
RETURN SHORT(CHR(n));
END InSChar;
(* Return the length (in SHORTCHARs) of the following array of shortchars to be read from the input stream. The length doesn't include the possible terminal 0X. *)
PROCEDURE (VAR r: Reader) InSCharsLen* (): INTEGER, NEW;
VAR
pos, i, n: INTEGER;
c: SHORTCHAR;
BEGIN (*InSCharsLen*)
pos := r.pos; i := 0; n := r.len;
LOOP
IF r.pos = n THEN
EXIT;
END;
c := r.InSChar();
IF c = 0X THEN
EXIT;
END;
INC(i);
END;
r.pos := pos;
RETURN i;
END InSCharsLen;
(* Read an array of shortchars from the input stream. Reading stops when a 0X has been read, or when LEN(c) - 1 shortchars have been read, or when the end of the input stream has been reached. In any case the string returned in c is 0X terminated. *)
PROCEDURE (VAR r: Reader) InSChars* (OUT c: ARRAY OF SHORTCHAR), NEW;
......@@ -528,6 +554,30 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
RETURN CHR(n);
END InChar;
(* Return the length (in CHARs) of the following array of chars to be read from the input stream. The length doesn't include the possible terminal 0X. *)
PROCEDURE (VAR r: Reader) InCharsLen* (): INTEGER, NEW;
VAR
pos, i, n: INTEGER;
c: CHAR;
BEGIN (*InCharsLen*)
pos := r.pos; i := 0; n := r.len;
LOOP
IF r.pos = n THEN
EXIT;
END;
c := r.InChar();
IF c = 0X THEN
EXIT;
END;
INC(i);
END;
r.pos := pos;
RETURN i;
END InCharsLen;
(* Read an array of chars from the input stream. Reading stops when a 0X has been read, or when LEN(c) - 1 chars have been read, or when the end of the input stream has been reached. In any case the string returned in c is 0X terminated. *)
PROCEDURE (VAR r: Reader) InChars* (OUT c: ARRAY OF CHAR), NEW;
......@@ -670,11 +720,11 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
END InitWriter;
(* Return the content of w.s (output stream of the writer) as an array of bytes *)
PROCEDURE (IN w: Writer) Write (): POINTER TO ARRAY OF BYTE, NEW;
PROCEDURE (IN w: Writer) Write (): Bytes, NEW;
VAR
a: POINTER TO ARRAY OF BYTE;
a: Bytes;
e: A.Elem;
i, n: INTEGER;
......@@ -873,7 +923,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
VAR
a: POINTER TO ARRAY OF BYTE;
a: Bytes;
r: Reader;
BEGIN (*ReadInt*)
......@@ -1170,7 +1220,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
n, i: INTEGER;
w: Writer;
a: ARRAY 1 OF BYTE;
aP: POINTER TO ARRAY OF BYTE;
aP: Bytes;
BEGIN (*CreatePage*)
IF base.pages.NumberOfElems() < base.pageNb THEN (* Allocate a new buffer page *)
......@@ -1296,7 +1346,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
VAR
p: Page;
a: POINTER TO ARRAY OF BYTE;
a: Bytes;
r: Reader;
BEGIN (*ReadSysPage*)
......@@ -1326,7 +1376,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
p.dirty := TRUE;
END WritePage;
(* Return if the header at position pos is free or not; return in cont this header *)
(* Return whether the header at position pos is free or not; return in cont this header *)
PROCEDURE (base: Database) FreeHead (pos: INTEGER; OUT cont: ClusterHead): BOOLEAN, NEW;
VAR
......@@ -1350,7 +1400,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
END;
END FreeHead;
(* Return if the tail at position pos is free or not; return in cont this tail *)
(* Return whether the tail at position pos is free or not; return in cont this tail *)
PROCEDURE (base: Database) FreeTail (pos: INTEGER; OUT cont: ClusterTail): BOOLEAN, NEW;
VAR
......@@ -1382,7 +1432,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
i, n: INTEGER;
w: Writer;
a: ARRAY 1 OF BYTE;
aP: POINTER TO ARRAY OF BYTE;
aP: Bytes;
BEGIN (*Do*)
WITH base: Database DO
......@@ -1942,7 +1992,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
VAR
p: Page;
a: POINTER TO ARRAY OF BYTE;
a: Bytes;
r: Reader;
BEGIN (*ReadPage*)
......@@ -1964,7 +2014,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
r: Reader;
w: Writer;
a: POINTER TO ARRAY OF BYTE;
a: Bytes;
pa: Data;
BEGIN (*ReadData*)
......@@ -1979,21 +2029,48 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
RETURN pa;
END ReadData;
(* Allocate a cluster of size size (bytes), for the data managed by d, in its database, and returns its position. size must be the size of the production of the method Data.Write of the data managed by d. *)
PROCEDURE (d: DataMan) AllocateData* (size: INTEGER): INTEGER, NEW;
(* Consider using WriteAllocateData instead.Allocate a cluster for data, managed by d, in the database of d, and return its position. Warning: AllocateData calls data.Write to find the size of data, be sure the value of data can be written and has its correct size. *)
PROCEDURE (d: DataMan) AllocateData* (data: Data): INTEGER, NEW;
VAR
w: Writer;
pos: INTEGER;
pa: Data;
BEGIN (*AllocateData*)
ASSERT(d.base.ref # NIL, 20);
ASSERT(size > 0, 21);
pa := d.base.NewDiskPage(size, d.fac, pos);
ASSERT(data # NIL, 21);
w.InitWriter(d.base.ref);
data.Write(w);
pa := d.base.NewDiskPage(w.s.NumberOfElems(), d.fac, pos);
RETURN pos;
END AllocateData;
(* Allocate a cluster for data, managed by d, in the database of d, and write data into it; return the position of the allocated cluster. *)
PROCEDURE (d: DataMan) WriteAllocateData* (data: Data): INTEGER, NEW;
VAR
r: Reader;
w: Writer;
a: Bytes;
ptr: INTEGER;
pa: Data;
BEGIN (*WriteAllocateData*)
ASSERT(d.base.ref # NIL, 20);
ASSERT(data # NIL, 21);
w.InitWriter(d.base.ref);
data.Write(w);
a := w.Write();
pa := d.base.NewDiskPage(LEN(a), d.fac, ptr);
r.InitReader(d.base.ref, a, 0);
d.base.ReadPage(ptr, d.fac).Read(r);
d.base.WritePage(ptr);
RETURN ptr;
END WriteAllocateData;
(* Write data, managed by d, at the position ptr in the database of d. *)
PROCEDURE (d: DataMan) WriteData* (ptr: INTEGER; data: Data), NEW;
......@@ -2001,6 +2078,7 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
r: Reader;
w: Writer;
a: Bytes;
BEGIN (*WriteData*)
ASSERT(d.base.ref # NIL, 20);
......@@ -2730,8 +2808,8 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
RETURN comp = eq;
END Search;
(* Erase from index ind the key key. If key does not belong to the index, ind.Erase does nothing. Modify the current position of the index only if the key was found; in this case, the current position is reset. *)
PROCEDURE (ind: Index) Erase* (key: Data), NEW;
(* Erase from index ind the key key. If key does not belong to the index, ind.Erase does nothing and returns FALSE, otherwise ir returns TRUE. If the current position of the index was on the erased key, it is reset. *)
PROCEDURE (ind: Index) Erase* (key: Data): BOOLEAN, NEW;
VAR
......@@ -2982,7 +3060,6 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
Era(ind.rootI, bNil, 0, ind.height);
IF minus1 THEN
DEC(ind.size);
ind.UpdateRoot;
END;
IF dec THEN (* Subtree has been erased... *)
pa := ind.baseI.ReadPage(ind.rootI, pif)(PageI);
......@@ -2992,9 +3069,12 @@ Prefixes are useful if keys are long or if their lengths vary much. In this case
ind.rootI := pa.elems[0].ptr;
ind.baseI.EraseDiskPage(pa.keys);
ind.baseI.EraseDiskPage(followP);
ind.UpdateRoot;
END;
END;
IF minus1 OR dec THEN
ind.UpdateRoot;
END;
RETURN minus1;
END Erase;
(* Return the number of different keys in ind *)
......
<html>
<head>
<title>WotWizard</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,width=device-width,minimal-ui">
<style>
body {
font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace;
}
p {
padding-left: 30px;
}
.definitions {
font-style: italic;
border-top: 1px solid #d8d8d8;
padding: 0;
margin-left: 30px;
padding-top: 10px;
padding-bottom: 10px;
}
.miseengarde {
font-style: italic;
}
blockquote {
margin-bottom: 20px;
}
blockquote h2 {
font-size: 18px;
margin-bottom: 15px;
}
blockquote p {
border-left: 1px solid #D1D1D1;
margin-left: 15px;
padding-left: 10px;
margin-top: 0px;
margin-bottom: 0px;
padding-top: 3px;
padding-bottom: 3px;
}
.sure {
color: green
}
.possible {
color: orange
}
.never {
color: red
}
h2.not_before_or_never:before {
content: "À partir du ";
}
h2.not_before_or_never:after {
content: "";
}
p.not_before_or_never:before {
content: "À partir du ";
}
p.not_before_or_never:after {
content: "";
}
</style>
<script src="./jquery.js"></script>
<script type="text/javascript">
function getURLParameter(name) {
var search = String(location.search)
var result = decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(search) || [null, ''])[1].replace(/\+/g, '%20')) || null
return result
}
function showByName(params) {
$('#contentName').show()
$('#contentDate').hide()
}
function showByDate(params) {
$('#contentDate').show()
$('#contentName').hide()
}
$( document ).ready(function() {
$('#radioByDate').change(function (e) {
showByDate()
})
$('#radioByName').change(function (e) {
showByName()
})
var byName = getURLParameter('s') == 'byName'
if (byName) {
$('#contentName').show()
$('#contentDate').hide()
} else {
$('#contentDate').show()
$('#contentName').hide()
}
})
$( document ).ready(function() {
$.getJSON('./WWMeta.json', function (jsonMeta) {
$.getJSON('./WWByDate.json', function (jsonByDate) {
var jsonByName = toJsonByName(jsonByDate)
console.log('Données WotWizard : ', jsonByDate)
$('#nbFolders').text(jsonMeta.dossNb)
$('#timeBCT').text(jsonMeta.now + ' BCT¹')
$('#currentBlock').text(jsonMeta.block)
$('#computationDuration').text(jsonMeta.computation_duration)
// By date
for (var i = 0; i < jsonByDate.dates.length; i++) {
var entry = jsonByDate.dates[i]
var html = '<blockquote>'
html += '<h2 class="' + (entry.after ? 'not_before_or_never' : 'at') + '">' + entry.date + '</h2>'
for (var j = 0; j < entry.names.length; j++) {
var name = entry.names[j]
var proba = name.proba
var probaClass = proba == 100 ? 'sure' : (isNaN(proba) ? 'never' : 'possible')
html += '<p>' + name.name + ' (<span class="' + probaClass + '">' + proba + '%</span>)</p>'
}
html += '</blockquote>'
$('#contentDate').append(html)
}
// By names
for (var i = 0; i < jsonByName.names.length; i++) {
var entry = jsonByName.names[i]
var html = '<blockquote>'
html += '<h2>' + entry.name + '</h2>'
for (var j = 0; j < entry.dates.length; j++) {
var date = entry.dates[j]
var proba = date.proba
var probaClass = proba == 100 ? 'sure' : (isNaN(proba) ? 'never' : 'possible')
html += '<p class="' + date.precision + '">' + date.date + ' (<span class="' + probaClass + '">' + proba + '%</span>)</p>'
}
html += '</blockquote>'
$('#contentName').append(html)
}
})
})
})
function toJsonByName(jsonByDate) {
var jsonByName = {
now: jsonByDate.now,
names: []
}
var names = {}
for (var i = 0; i < jsonByDate.dates.length; i++) {
var entry = jsonByDate.dates[i]
for (var j = 0; j < entry.names.length; j++) {
var name = entry.names[j]
names[name.name] = names[name.name] || { name: name.name, dates: [] }
names[name.name].dates.push({
precision: (entry.after ? 'not_before_or_never' : 'at'),
date: entry.date,
proba: name.proba
})
}
}
for (var name of Object.keys(names)) {
jsonByName.names.push(names[name])
}
jsonByName.names.sort(function (a, b) {
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1
return 0
})
return jsonByName
}
</script>
</head>
<body>
<h2>Dossiers en attente : <span id="nbFolders"></span></h2>
<h3>Heure actuelle : <span id="timeBCT"></span></h3>
<h3>Bloc courant : #<span id="currentBlock"></span></h3>
<h3>Durée du calcul WotWizard : <span id="computationDuration"></span></h3>
<div class="groups">
<p>
<input type="radio" name="sort" id="radioByDate" checked>
<label for="radioByDate">Grouper par date</label>
</p>
<p>
<input type="radio" name="sort" id="radioByName">
<label for="radioByName">Grouper par UID</label>
</p>
</div>
<div id="contentDate"></div>
<div id="contentName"></div>
<p class="miseengarde">Ces prévisions sont sujettes à modifications à mesure que de nouveaux dossiers ou de nouvelles certifications internes (de membre à membre) ou externes (de membre à nouveau venu) apparaissent. Cette page est mise à jour toutes les 5 minutes, rafraîchissez la page pour voir les modifications.</p>
<p class="miseengarde">Note 1 : la mention « À partir du » indique une date lointaine à partir de laquelle les probabilités sont trop difficiles à obtenir. Un dossier présent sous ce libellé à des chances de ne jamais passer.</p>
<p class="miseengarde">Note 2 : toutes les dates/heures sont exprimées ici en référence BCT.</p>
<p class="definitions">¹ : BCT signifie « BlockChain Time », ou heure blockchain. Équivalent à UTC+0 avec un retard d'une heure en moyenne.</p>
</body>
</html>
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment