Project - Random Clock

This project demonstrates many functionalities which help show what Annex-Wifi Basic is capable of.

Click on the digital clock to load a new style with random settings depending on what options are set.
Click the 'Undo' icon (top right) to revert back to the previous style settings.
Click the Options Menu icon (top right) to open a slide-out 'overlay' showing all options and settings.
Select individual settings for automatic timed random change if wished.
Adjust any settings manually to achieve a desired result, then save the style settings to file for loading later.

OVERVIEW:
All pre-defined options are changeable at the top of the script.
All options are changeable from the slideout menu, irrespective of whether the checkbox's are ticked or not.
The checkbox's specify what options are randomly changed when the digital clock is changed by mouse click or automatic random timer.
Some 'selective' options will cause all the random checkbox's to be un-ticked to prevent accidental random loss of other settings.
Every time an option is changed the screen will be 'repainted' to display the changes.
Select All and Clear All buttons are provided for convenience.
The Save button is linked with the Undo (previous) style... so when Saving, the previously saved style is loaded and available to view using Undo.
The default settings filename is called "settings.ini" which can be over-ridden at the bottom of the slideout menu.
Or the settings file can mirror the script filename by un-commenting the 4th line of the script... confirm correct filename at bottom of slideout menu.
 
HINT:  Check the Instructions at the bottom of the slideout.

FONTS: The script has the ability to use embedded fonts (see previous project) - add filenames into the list of available fonts:
fonts$ = "dig7monoitalic.ttf,dig7mono.ttf,scoreboard.ttf,default"
The pre-defined default is shown below, but if not found, the browsers default system font will be used instead.: 
font$ = "dig7monoitalic.ttf"

NOTE: the script has kept being evolved to squeeze too much into limited resources, so to keep changing fonts will eventually be a step too far.
My policy has been to stuff in as much as possible, so people have a bigger pot from which to take anything of interest after seeing it in operation.
Also, bear in mind I am a hacker not a programmer, so a rewrite incorporating learned knowledge and experience could be a lot more efficient.
When ticked, the Random Timer gives random changes to all selected checkbox items at the selected timer interval.
The automatic Random Timer facility gives interesting results, but should be considered a severe stress test which will eventually cause failure.
If and when you crash the system, you need to reboot the device, then Reconnect the browser page, then Save (or Open) the file in the editor.


NOTE: the very first and very last fields of the slideout are both textbox's which offer opportunity to edit their variables contents (Random Timer value, and Settings Filename), but remember to press Enter key after making changes or the variable will not be updated and they will be lost.
































Basic:
'  Random Digital Clock V2
option lowram 10000
filename$ = "/program/settings.ini"
'filename$ = word$(BAS.FILENAME$,1,".") + ".ini" 'Un-comment this line to save settings to 'this scriptname'.ini
timerflag = 0
duration = 20
countdown = duration
changes = 0
' The following 'flags' specify the default startup condition of the menu checkbox's
rand = 0
fontflag = 0
fontstyleflag = 0
fontweightflag = 0
fontcolflag = 1
fontbakflag = 1
fontgradflag = 1
fontpadflag = 0
fontsizeflag = 0
bordsizeflag = 0
bordradflag = 1
bordcolflag = 0
backgroundflag = 0
' The follwing are where available options are defined followed by an appropriate default option
fonts$ = ""
'fonts$ = "dig7monoitalic.ttf,dig7mono.ttf,scoreboard.ttf,default"
font$ = "dig7monoitalic.ttf"
fontstyles$ = "normal,italic"
fontstyle$ = "normal"
fontstyle = val(fontstyle$)
fontweights$ = "normal,bold"
fontweight$ = "normal"
fontweight = val(fontweight$)
fontcol$ = "#ff0000"
fontbak$ = "#ffffff"
fontgrad$ = "#888888"
fontpads$ = "0,1,2,3,4,5,6"
fontpad$ = "3"
fontsizes$ = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20"
fontsize$ = "10"
bordsizes$ = "0,1,2,3,4,5,6"
bordsize$ = "1"
bordrads$ = "0,1,2,3,4,5,6,7,8,9"
bordrad$ = "1"
bordcol$ = "#aaaaaa"
R=0:G=0:B=0 
bakcol$ = "#ffffff"
oldR = R
oldG = G
oldB = B
a$ = ""
b$ = ""
oldfilename$ = filename$
ONHTMLCHANGE change
gosub paint
timer0 1000, clock
wait

paint:
cls
gosub main
gosub rightmenuA
gosub rightmenuB
return

rightmenuA:
' Defines the right-hand slide-out menu
a$ = |<!DOCTYPE html><html><head>|
a$ = a$ + |<style>|
a$ = a$ + |input { width:120px;}|
a$ = a$ + |body { font-family: "Lato", sans-serif;}|
a$ = a$ + |.sidenav {opacity: 0.78;height: 100%; width: 0; position: fixed; z-index: 1; top: 0; right: 0; background-color: black;|
a$ = a$ + |overflow-x: hidden; overflow-y: hidden;transition: 0.5s; padding-top: 0px;}|
a$ = a$ + |.sidenav a { padding: 8px 8px 8px 32px; text-decoration: none; font-size: 22px; color: #818181; display: block; transition: 0.3s;}|
a$ = a$ + |.sidenav a:hover { color: #f1f1f1;}|
a$ = a$ + |.sidenav .closebtn { position: absolute; top: 0; right: 24px; font-size: 36px; margin-left: 50px;}|
a$ = a$ + |p color: lightgrey; text-align:center;font-size:.8em;font-style:italic;}|
a$ = a$ + |@media screen and (max-height: 400px) { .sidenav {padding-top: 15px;} .sidenav a {font-size: 16px;}}|
a$ = a$ + |.pars td:nth-child(1){padding-left:1em;color:cyan} |
a$ = a$ + |.pars td:nth-child(2){padding-left:0em;transform: scale(1.6);}|
a$ = a$ + |.pars td:nth-child(3){text-align:left;padding-left:1em;} |
a$ = a$ + |.pars button:hover { color:blue; background-color: yellow;} |
a$ = a$ + |</style></head>|
a$ = a$ + |<body>|
html a$ : pause 200
a$ = |<div id="mySidenav" class="sidenav">|
a$ = a$ + |<a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>|
a$ = a$ + |<h3 style="color:yellow;text-align:center;padding:0;">SETTINGS</h3>|
a$ = a$ + |<table id="pars" class="pars" style="width:100%;color:white;"> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Random Timer</td> |
a$ = a$ + |<td>| + checkbox$(timerflag) + |</td> |
a$ = a$ + |<td>| + textbox$(duration,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Name</td> |
a$ = a$ + |<td>| + checkbox$(fontflag) + |</td> |
a$ = a$ + |<td>| + listbox$(font$,fonts$,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Size</td> |
a$ = a$ + |<td>| + checkbox$(fontsizeflag) + |</td> |
a$ = a$ + |<td>| + listbox$(fontsize$,fontsizes$,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Style</td> |
a$ = a$ + |<td>| + checkbox$(fontstyleflag,"cb") + |</td> |
a$ = a$ + |<td>| + listbox$(fontstyle$,fontstyles$,"tb") + |</td> |
a$ = a$ + |</tr> |
html a$: pause 200: a$ = ""
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Weight</td> |
a$ = a$ + |<td>| + checkbox$(fontweightflag) + |</td> |
a$ = a$ + |<td>| + listbox$(fontweight$,fontweights$,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Padding</td> |
a$ = a$ + |<td>| + checkbox$(fontpadflag) + |</td> |
a$ = a$ + |<td>| + listbox$(fontpad$,bordrads$,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Font Colour</td> |
a$ = a$ + |<td>| + checkbox$(fontcolflag) + |</td> |
a$ = a$ + |<td><input type="color" data-var="fontcol$" onchange="cmdChange(event)" value="| + fontcol$ + |"></td>|
a$ = a$ + |</tr> |
html a$: pause 200: a$ = ""
a$ = a$ + |<tr> |
a$ = a$ + |<td>Background Colour</td> |
a$ = a$ + |<td>| + checkbox$(fontbakflag) + |</td> |
a$ = a$ + |<td><input type="color" data-var="fontbak$" onchange="cmdChange(event)" value="| + fontbak$ + |"></td>|
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Gradient Colour</td> |
a$ = a$ + |<td>| + checkbox$(fontgradflag) + |</td> |
a$ = a$ + |<td><input type="color" data-var="fontgrad$" onchange="cmdChange(event)" value="| + fontgrad$ + |"></td>|
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Border Colour</td> |
a$ = a$ + |<td>| + checkbox$(bordcolflag) + |</td> |
a$ = a$ + |<td><input type="color" data-var="bordcol$" onchange="cmdChange(event)" value="| + bordcol$ + |"></td>|
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Border Size</td> |
a$ = a$ + |<td>| + checkbox$(bordsizeflag) + |</td> |'
a$ = a$ + |<td>| + listbox$(bordsize$,bordrads$,"tb") + |</td> |
html a$: pause 200: a$ = ""
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Border Radius</td> |
a$ = a$ + |<td>| + checkbox$(bordradflag) + |</td> |
a$ = a$ + |<td>| + listbox$(bordrad$,bordrads$,"tb") + |</td> |
a$ = a$ + |</tr> |
a$ = a$ + |<tr> |
a$ = a$ + |<td>Screen Colour</td> |
a$ = a$ + |<td>| + checkbox$(backgroundflag) + |</td> |
a$ = a$ + |<td><input type="color" data-var="bakcol$" onchange="cmdChange(event)" value="| + bakcol$ + |"></td>|
a$ = a$ + cssid$("tb", "width:120px;text-align:center;")
a$ = a$ + |</tr> |
a$ = a$ + |<tr><th colspan="3" style='text-align:center;font-size:4px;color:black;'>|
extractrgb bakcol$
a$ = a$ + slider$(R,0,255,"R")
a$ = a$ + slider$(G,0,255,"G")
a$ = a$ + slider$(B,0,255,"B") + |&nbsp; </th></tr>|
a$ = a$ + cssid$("R", "width:118;height:10;background:red;text-align:right;")
a$ = a$ + cssid$("G", "width:118;height:10;background:green;text-align:center;")
a$ = a$ + cssid$("B", "width:118;height:10;background:blue;text-align:left;padding-right:.6em;")
html a$: pause 200: a$ = ""
a$ = a$ + |<tr><td colspan="3" style='text-align:left;padding-right:.6em;'>| + button$("Black",black) + |&nbsp;| + button$("White",white)
a$ = a$ + |&nbsp;&nbsp;&nbsp;|
a$ = a$ + button$("Clear all",none) + |&nbsp;| + button$("Select all",all)
a$ = a$ + |&nbsp;&nbsp;&nbsp;|
a$ = a$ + button$("Save",save) + |&nbsp;| + button$("Load",load) + |</td></tr> |
a$ = a$ + |<tr><th colspan="3" style='text-align:right;font-size:1em;color:black;'> &nbsp; </th></tr>|
a$ = a$ + |<tr><th colspan="3" style='text-align:center;color:yellow;'>INSTRUCTIONS</th></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |Tick checkbox for random setting, un-tick to use listed setting</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |A ticked random checkbox over-rides the displayed value</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |If choosing manual setting, ensure checkbox is unticked</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |'Timed Random Change' is at the shown interval in seconds</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |'Black' & 'White' buttons set background if checkbox un-ticked</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |R G B sliders provide manual background colour adjustment</td></tr>|
html a$: pause 200: a$ = ""
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |'Select all' to randomly change all settings</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |'Clear all' to manually select individual settings</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |Current settings can be Saved to file then Loaded later</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |Loading previous settings automatically unticks all checkboxs</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |Settings take effect the next time the clock display is clicked</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.4 .6em 0 .6em;color:lightgray;font-size:.9em;'>|
a$ = a$ + |Clicking on the clock will automatically close the menu</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='padding:.3 .6em 0 .6em;color:lightgray;font-size:.9em;line-height: 1em;'>|
a$ = a$ + |Clicking the top-right <b style='padding:.2em;color:white;font-size:1.6em;'>&#8630;</b> icon will revert to previous settings</td></tr>|
a$ = a$ + |<tr><td colspan="3" style='text-align:center;font-size:1.0em;'>Filename:| + textbox$(filename$,"fn") + |</td>|
a$ = a$ + cssid$("fn", "font-size:1em;background:black; color:white; border:0; padding:.5em;width:220px;")
a$ = a$ + |</table>|
a$ = a$ + |</div>|
a$ = a$ + |<span style="position:absolute;top:7;right:29px;margin-left:350px;font-size:30px;color:white;cursor:pointer" onclick="openNav()">&#9776;</span>|
a$ = a$ + |<span data-var='undo' onclick='cmdButton(this)' style="position:absolute;top:0;right:76px;margin-left:50px;font-size:38px;color:white;cursor:pointer" >&#8630;</span>|
a$ = a$ + |</body></html>|
html a$
oldR = R
oldG = G
oldB = B
oldfilename$ = filename$
refresh
return

rightmenuB:
' Defines slide-menu javascript
a$ = ""
a$ = a$ + |function openNav() { document.getElementById("mySidenav").style.width = "430PX";}|
a$ = a$ + |function closeNav() { document.getElementById("mySidenav").style.width = "0";}|
trace "jscript" + a$
return

main:
' Paints the digital clock
a$ = "<style> @font-face { font-family: clock; src: url('/font/" + font$ + "');}"
a$ = a$ + "body { background-color: " + bakcol$ + ";}"
a$ = a$ + "</style>"
html a$: pause 300: a$ = ""
if fontgrad$ <> "" then fontbakcol$ = "linear-gradient(" + fontbak$ + "," + fontgrad$ + ")" else fontbakcol$ = fontbak$
digit$ = "padding:." + fontpad$ + "em; margin: auto; color:" + fontcol$ + "; background:" + fontbakcol$ + "; text-align: center; font: 30px/70% clock;"
digit$ = digit$ + "font-size:" + fontsize$ + "em;border-radius:." + bordrad$ + "em;border:." + bordsize$ + "em solid " + bordcol$ + ";"
digit$ = digit$ + "font-style:" + fontstyle$ + ";font-weight:" + fontweight$ + ";"
a$ = a$ + string$(8 - (int(val(fontsize$) / 4)),"<BR>")
a$ = a$ + "<div id='clock' data-var='randomise' onclick='cmdButton(this)' style='display: table; margin-right: auto; margin-left: auto;" + digit$ + ";'>" + time$ + "</div>"
html a$
return

clock:
' Updates the digital display
jscall "_$('clock').innerHTML = """ + time$ + """"
if timerflag > 0 then countdown = countdown - 1
if countdown = 1 then
 timer0 0
 countdown = duration
 gosub randomise
 timer0 1000, clock
endif
return

getpars:
if WORD.GETPARAM$(a$,"font$") <> ""  then font$ = WORD.GETPARAM$(a$,"font$")
if WORD.GETPARAM$(a$,"fontcol$") <> ""  then fontcol$ = WORD.GETPARAM$(a$,"fontcol$")
if WORD.GETPARAM$(a$,"fontstyle$") <> ""  then fontstyle$ = WORD.GETPARAM$(a$,"fontstyle$")
if WORD.GETPARAM$(a$,"fontweight$") <> ""  then fontweight$ = WORD.GETPARAM$(a$,"fontweight$")
if WORD.GETPARAM$(a$,"fontbak$") <> ""  then fontbak$ = WORD.GETPARAM$(a$,"fontbak$")
if WORD.GETPARAM$(a$,"fontgrad$") <> ""  then fontgrad$ = WORD.GETPARAM$(a$,"fontgrad$")
if WORD.GETPARAM$(a$,"fontgradflag$") <> ""  then fontgradflag = val(WORD.GETPARAM$(a$,"fontgradflag$"))
if WORD.GETPARAM$(a$,"fontpad$") <> ""  then fontpad$ = WORD.GETPARAM$(a$,"fontpad$")
if WORD.GETPARAM$(a$,"fontsize$") <> ""  then fontsize$ = WORD.GETPARAM$(a$,"fontsize$")
if WORD.GETPARAM$(a$,"bordsize$") <> ""  then bordsize$ = WORD.GETPARAM$(a$,"bordsize$")
if WORD.GETPARAM$(a$,"bordrad$") <> ""  then bordrad$ = WORD.GETPARAM$(a$,"bordrad$")
if WORD.GETPARAM$(a$,"bordcol$") <> ""  then bordcol$ = WORD.GETPARAM$(a$,"bordcol$")
if WORD.GETPARAM$(a$,"bakcol$") <> ""  then bakcol$ = WORD.GETPARAM$(a$,"bakcol$")
return

setpars:
WORD.SETPARAM  a$, "font$", font$
WORD.SETPARAM  a$, "fontstyle$", fontstyle$
WORD.SETPARAM  a$, "fontweight$", fontweight$
WORD.SETPARAM  a$, "fontcol$", fontcol$
WORD.SETPARAM  a$, "fontbak$", fontbak$
WORD.SETPARAM  a$, "fontgrad$", fontgrad$
WORD.SETPARAM  a$, "fontgradflag$", str$(fontgradflag )
WORD.SETPARAM  a$, "fontpad$", fontpad$
WORD.SETPARAM  a$, "fontsize$", fontsize$
WORD.SETPARAM  a$, "bordsize$", bordsize$
WORD.SETPARAM  a$, "bordrad$", bordrad$
WORD.SETPARAM  a$, "bordcol$", bordcol$
WORD.SETPARAM  a$, "bakcol$", bakcol$
return

save:
' Saves settings to file
a$ = ""
if FILE.EXISTS(filename$) > 0 then a$ = FILE.READ$(filename$)
if a$ <> "" then b$ = a$
gosub setpars
FILE.SAVE filename$, a$
gosub paint
return

load:
' Loads settings from file
a$ = ""
gosub setpars
b$ = a$
a$ = ""
if FILE.EXISTS(filename$) > 0 then a$ = FILE.READ$(filename$)
gosub getpars
gosub none
refresh
extractrgb bakcol$
gosub paint
return

undo:
print "UNDO"
a$ = b$
gosub getpars
extractrgb bakcol$
gosub paint
return

all:
' This subroutine 'ticks' all the checkbox's to obtain all random values
fontflag = 1
fontstyleflag = 1
fontweightflag = 1
fontcolflag = 1
fontbakflag = 1
fontgradflag = 1
fontpadflag = 1
fontsizeflag = 1
bordsizeflag = 1
bordradflag = 1
bordcolflag = 1
backgroundflag = 1
gosub paint
return

none:
' This subroutine 'clears' (unticks) all the checkbox's to prevent overwriting with random values
fontflag = 0
fontstyleflag = 0
fontweightflag = 0
fontcolflag = 0
fontbakflag = 0
fontgradflag = 0
fontpadflag = 0
fontsizeflag = 0
bordsizeflag = 0
bordradflag = 0
bordcolflag = 0
backgroundflag = 0
refresh
return

white:
bakcol$ = "#ffffff"
gosub none
gosub paint
return

black:
bakcol$ = "#000000"
gosub none
gosub paint
return

change:
refresh
if (oldR <> R) or (oldG <> G) or (oldB <> B) then
 bakcol$ = "#" + right$("00000" + hex$((R << 16) + (G << 8) + B), 6)
 gosub none
endif
oldR = R: oldG = G: oldB = B
gosub paint
return

sub randomcol(ret$)
local R, G, B
R = rnd(256)+1: G = rnd(256)+1: B = rnd(256)+1:
ret$ = "#" + right$("00000" + hex$((R << 16) + (G << 8) + B), 6)
end sub

sub randlist(ret$,list$)
rand = rnd(word.count(list$,",")) + 1
ret$ = word$(list$,rand,",")
wlog "rand=" + str$(rand) + "  ret$=" + ret$ + "  memfree=" + str$(ramfree)
end sub

sub extractrgb(t$)
local r$,g$,b$
if mid$(t$,1,1) = "#" then
 r$ = "&h" + mid$(t$,2,2)
 g$ = "&h" + mid$(t$,4,2)
 b$ = "&h" + mid$(t$,6,2)
 R = val(r$)
 G = val(g$)
 B = val(b$)
endif
refresh
end sub

randomise:
' This routine obtains random values for all checkbox's that are ticked
changes = changes + 1
print " "
print "CHANGES=";changes
a$ = ""
gosub setpars
b$ = a$
if fontflag > 0 then randlist font$, fonts$
if fontstyleflag > 0 then
 randlist fontstyle$, fontstyles$
 fontstyle = rand
endif
if fontweightflag > 0 then
 randlist fontweight$, fontweights$
 fontweight = rand
endif
if fontcolflag > 0 then randomcol fontcol$
if fontbakflag > 0 then randomcol fontbak$
if fontgradflag > 0 then randomcol fontgrad$
if bordcolflag > 0 then randomcol bordcol$
if fontpadflag > 0 then
fontpad$ = str$(rnd(3) + 1 + fontstyle + fontweight)
endif
if fontsizeflag > 0 then fontsize$ = str$(rnd(10) + 3)
if bordsizeflag > 0 then bordsize$ = str$(rnd(7))
if bordradflag > 0 then bordrad$ = str$(rnd(9))
if backgroundflag > 0 then randomcol bakcol$
'print "font$=";font$;", fontsize$=";fontsize$; ", fontstyle$=";fontstyle$;", fontweight$=";fontweight$;", fontcol$=";fontcol$;
'print ", fontbak$=";fontbak$;", fontpad$=";fontpad$;", bordsize$="; bordsize$;", bordcol$=";bordcol$;", bordrad$=";bordrad$;", bakcol$";bakcol$
gosub paint
return
'---------------------- END -----------------------