42 Commits

Author SHA1 Message Date
f1616d0240 fix list view rendering text 2018-03-12 23:59:14 +01:00
bb0a20b2ad fix setting error 2018-03-12 23:48:46 +01:00
377834e0ff fix setting error 2018-03-12 23:36:39 +01:00
7a609e3270 fix setting error 2018-03-12 23:20:06 +01:00
a06d3258f9 add Setting to the main build 2018-03-12 22:48:25 +01:00
56cf8ea770 fix File bug 2018-03-12 22:47:23 +01:00
d2677eb380 some know bug in File is not fixed yet 2018-03-12 19:48:22 +01:00
9d5f2250ba add buttons to Fime 2018-03-12 19:33:11 +01:00
d310d2c03b Finish package setting & add FR language 2018-03-12 18:55:40 +01:00
7fd6492a31 afx-list-view now can add action buttons 2018-03-12 11:33:33 +01:00
6c7aec69b7 fix MarketPlace ui bug when language change 2018-03-12 10:35:58 +01:00
e01d41c76b fix tab container update 2018-03-12 10:22:51 +01:00
02f8a256d3 add missing wp 2018-03-12 10:03:17 +01:00
07bb58b7eb add appearance setting 2018-03-12 00:42:14 +01:00
8fef0c5e96 add setting package 2018-03-11 21:31:40 +01:00
10015d99b0 font-awesome is used as default icon font for the entire system 2018-03-11 12:32:37 +01:00
800c95830d normal string format and locale support string format 2018-03-10 23:24:53 +01:00
7fefc17f04 fix menu bug 2018-03-10 23:16:48 +01:00
702a83df6a allow to overide locale method __() to all object 2018-03-10 22:46:28 +01:00
6367c321da add FormatedString class, automatically translate to new locale when locale is set 2018-03-10 20:42:09 +01:00
88cf90ae50 minor fix 2018-03-10 15:42:21 +01:00
a624d853ed add language make support to makefile 2018-03-10 15:40:25 +01:00
1b9e6e88fa Add global locale change event, application now automatically change language when the event is triggered 2018-03-10 12:22:01 +01:00
45c89be5be add vi_VN locale 2018-03-10 01:32:18 +01:00
d072566be8 all packages now support localisation 2018-03-10 01:05:34 +01:00
9e0cd29030 add localisation support, allow multi-languages 2018-03-09 19:54:33 +01:00
696114e2f7 add use strict mode to the core API 2018-03-09 10:11:15 +01:00
30da6fa8fc make MarketPlace singleton 2018-03-08 23:45:12 +01:00
8d3ae96f01 fix uninstall bug in market place 2018-03-08 23:33:32 +01:00
318f26d164 fix uninstall bug in market place 2018-03-08 23:29:37 +01:00
c82da84240 Fix CodeBlock 2018-03-08 22:58:14 +01:00
4afc368bdd code block 2018-03-08 19:33:50 +01:00
8877f46771 support screenshot in MarketPlace 2018-03-07 19:32:48 +01:00
a9c3be2d75 improve Blogger 2018-03-07 14:19:23 +01:00
5020fb4ecc Merged
Merge branch 'master' of https://github.com/lxsang/antos
2018-03-07 10:57:05 +01:00
241b8caa6b improve database reading in Blogger 2018-03-07 10:57:01 +01:00
8e02bf6dc7 improve Blogger 2018-03-06 20:51:37 +01:00
946bf9df5e minor bug fix 2018-03-06 00:16:42 +01:00
d8b8037b3e minor bug fix 2018-03-06 00:06:44 +01:00
d9bd567271 update MarketPlace 2018-03-05 23:49:25 +01:00
8ae2f529f7 minor fix 2018-03-05 22:57:33 +01:00
88a78c7eef Blogger now support embedded youtube video 2018-03-05 14:58:20 +01:00
104 changed files with 5583 additions and 431 deletions

View File

@ -22,9 +22,9 @@ coffees= src/core/core.coffee\
packages = CoreServices NotePad wTerm ActivityMonitor Files MarkOn MarketPlace Blogger Preview
packages = CoreServices NotePad wTerm ActivityMonitor Files MarkOn MarketPlace Blogger Preview Setting
main: build_coffees build_tags build_themes schemes libs build_packages
main: build_coffees build_tags build_themes schemes libs build_packages languages
- cp src/index.html $(BUILDDIR)/
lite: build_coffee build_tag build_theme schemes build_packages
@ -56,12 +56,20 @@ testdata:
cp src/core/handlers/jsons/* $(BUILDDIR)/resources/jsons
build_tags:
@echo "$(BLUE)Building tag files$(NC)"
-mkdir $(BUILDDIR)/resources
-mkdir $(BUILDDIR)/resources
-rm $(BUILDDIR)/resources/antos_tags.js
for f in src/core/tags/*; do (cat "$${f}"; echo) >> $(BUILDDIR)/resources/antos_tags.js; done
build_themes: antos_themes_build
languages:
-mkdir $(BUILDDIR)/resources
-mkdir $(BUILDDIR)/resources/languages
cp src/core/languages/*.json $(BUILDDIR)/resources/languages/
genlang:
read -r -p "Enter locale: " LOCAL;\
./src/core/languages/gen.sh ./src ./src/core/languages/$$LOCAL.json
build_themes: antos_themes_build
cp -r src/themes/system $(BUILDDIR)/resources/themes/
antos_themes_build:
@echo "$(BLUE)Building themes name: antos$(NC)"
@ -104,6 +112,7 @@ uglify:
# npm install minify -g
# uglify the css
minify --output $(BUILDDIR)/resources/themes/antos/antos.css $(BUILDDIR)/resources/themes/antos/antos.css
minify --output $(BUILDDIR)/resources/themes/system/font-awesome.css $(BUILDDIR)/resources/themes/system/font-awesome.css
#uglify each packages
for d in $(packages); do\

View File

@ -77,8 +77,8 @@ class BaseApplication extends this.OS.GUI.BaseModel
[{
text: _OS.APP[@name].meta.name,
child: [
{ text: "About", dataid: "#{@name}-about" },
{ text: "Exit", dataid: "#{@name}-exit" }
{ text: "__(About)", dataid: "#{@name}-about" },
{ text: "__(Exit)", dataid: "#{@name}-exit" }
]
}]
mn = mn.concat @menu() || []

View File

@ -54,16 +54,17 @@ class BasicDialog extends BaseDialog
init: () ->
@title = @name if not @title
html = "<afx-app-window data-id = 'dia-window' apptitle='#{@title}' width='#{@conf.width}' height='#{@conf.height}'>
html = "<afx-app-window data-id = 'dia-window' width='#{@conf.width}' height='#{@conf.height}'>
<afx-vbox>"
html += "<#{v.tag} #{v.att} style = 'margin-left:5px; margin-right:5px;' data-id = 'content#{k}'></#{v.tag}>" for k,v of @conf.tags
html += "<div data-height = '35' style=' text-align:right;padding-top:3px;'>"
html += "<afx-button data-id = 'bt#{k}' text = '#{v.label}' style='margin-right:5px;'></afx-button>" for k,v of @conf.buttons
html += "</div></afx-vbox></afx-app-window>"
html += "</div><div data-height='5'></div></afx-vbox></afx-app-window>"
#render the html
_GUI.htmlToScheme html, @, @host
main: () ->
@scheme.set "apptitle", @title
@scheme.set "minimizable", false
@scheme.set "resizable", @conf.resizable if @conf.resizable isnt undefined
me = @
@ -79,15 +80,15 @@ class PromptDialog extends BasicDialog
constructor: () ->
super "PromptDialog", {
tags: [
{ tag: "afx-label", att: "data-height = '20'" },
{ tag: "input", att: "type = 'text'" }
{ tag: "afx-label" },
{ tag: "input", att: "type = 'text' data-height='25'" }
],
width: 200,
height: 100,
height: 120,
resizable: false,
buttons: [
{
label: "0k",
label: "__(Ok)",
onclick: (d) ->
txt = (d.find "content1").value
return d.quit() if txt is ""
@ -95,7 +96,7 @@ class PromptDialog extends BasicDialog
d.quit()
},
{
label: "Cancel",
label: "__(Cancel)",
onclick: (d) -> d.quit()
}
],
@ -115,21 +116,21 @@ class CalendarDialog extends BasicDialog
super "CalendarDialog", {
tags: [{ tag: 'afx-calendar-view' }],
width: 300,
height: 220,
height: 230,
resizable: false,
buttons: [
{
label: 'Ok',
label: "__(Ok)",
onclick: (d) ->
date = (d.find "content0").get "selectedDate"
if date
d.handler date if d.handler
d.quit()
else
d.notify "Please select a date"
d.notify __("Please select a date")
},
{
label: 'Cancel',
label: "__(Cancel)",
onclick: (d) -> d.quit()
}
]
@ -145,7 +146,7 @@ class ColorPickerDialog extends BasicDialog
resizable: false,
buttons: [
{
label: 'Ok',
label: "__(Ok)",
onclick: (d) ->
c = (d.find "content0").get "selectedColor"
if c
@ -155,7 +156,7 @@ class ColorPickerDialog extends BasicDialog
d.notify "Please select a color"
},
{
label: 'Cancel',
label: "__(Cancel)",
onclick: (d) -> d.quit()
}
]
@ -169,7 +170,7 @@ class InfoDialog extends BasicDialog
width: 250,
height: 300,
resizable: true,
buttons: [ { label: 'Cancel', onclick: (d) -> d.quit() } ],
buttons: [ { label: "__(Cancel)", onclick: (d) -> d.quit() } ],
filldata: (d) ->
return unless d.data
rows = []
@ -188,12 +189,12 @@ class YesNoDialog extends BasicDialog
resizable: true,
buttons: [
{
label: "Yes", onclick: (d) ->
label: "__(Yes)", onclick: (d) ->
d.handler true if d.handler
d.quit()
},
{
label: "No", onclick: (d) ->
label: "__(No)", onclick: (d) ->
d.handler false if d.handler
d.quit()
}
@ -215,14 +216,14 @@ class SelectionDialog extends BasicDialog
resizable: false,
buttons: [
{
label: "Ok", onclick: (d) ->
label: "__(Ok)", onclick: (d) ->
el = d.find "content0"
it = el.get "selected"
return unless it
d.handler it if d.handler
d.quit()
},
{ label: "Cancel", onclick: (d) -> d.quit() }
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
],
filldata: (d) ->
return unless d.data
@ -239,11 +240,11 @@ class AboutDialog extends BaseDialog
super "AboutDialog"
init: () ->
@render "os:///resources/schemes/about.html"
@render "os://resources/schemes/about.html"
main: () ->
mt = @meta()
@scheme.set "apptitle", "About: #{mt.name}"
@scheme.set "apptitle", __("About: {0}",mt.name)
(@find "mylabel").set "*", {icon:mt.icon, iconclass:mt.iconclass, text:"#{mt.name}(v#{mt.version})"}
($ @find "mydesc").html mt.description
# grid data for author info
@ -259,34 +260,33 @@ class FileDiaLog extends BaseDialog
super "FileDiaLog"
init: () ->
@render "os:///resources/schemes/filedialog.html"
@render "os://resources/schemes/filedialog.html"
main: () ->
fileview = @find "fileview"
location = @find "location"
filename = @find "filename"
me = @
@scheme.set "apptitle", "#{@title}"
@scheme.set "apptitle", @title
fileview.set "fetch", (e, f) ->
return unless e.child
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
return me.error __("Resource not found: {0}", e.child.path) if d.error
f d.result
location.set "onlistselect", (e) ->
return unless e and e.data.path
e.data.path.asFileHandler().read (d) ->
if(d.error)
return me.error "Resource not found #{e.data.path}"
return me.error __("Resource not found: {0}", e.data.path)
fileview.set "path", e.data.path
fileview.set "data", d.result
location.set "items", ( i for i in @systemsetting.VFS.mountpoints when i.type isnt "app" )
location.set "selected", 0 unless location.get "selected"
fileview.set "onfileselect", (f) ->
($ filename).val f.filename if f.type is "file"
(@find "bt-ok").set "onbtclick", (e) ->
f = fileview.get "selectedFile"
return me.notify "Please select a file" unless f
return me.notify __("Please select a file") unless f
if me.data and me.data.mimes
#verify the mime
m = false
@ -294,7 +294,7 @@ class FileDiaLog extends BaseDialog
if f.mime.match (new RegExp v, "g")
m = true
break
return me.notify "Only #{me.data.mimes.join(",")} could be selected" unless m
return me.notify __("Only {0} could be selected", me.data.mimes.join(",")) unless m
d = f.path
d = f.path.asFileHandler().parent() if f.type is "file"
me.handler d, ($ filename).val(), f.path if me.handler
@ -307,5 +307,6 @@ class FileDiaLog extends BaseDialog
if @data and @data.file
($ filename).css("display", "block").val @data.file.basename or "Untitled"
@trigger "resize"
fileview.set "showhidden", @data.hidden if @data and @data.hidden
this.OS.register "FileDiaLog", FileDiaLog

View File

@ -1,5 +1,6 @@
class BaseModel
constructor: (@name, @args) ->
me = @
@observable = riot.observable()
@_api = self.OS.API
@_gui = self.OS.GUI
@ -8,7 +9,8 @@ class BaseModel
@on "exit", () -> me.quit()
@host = "#desktop"
@dialog = undefined
@subscribe "systemlocalechange", (name) ->
me.scheme.update() if me.scheme
render: (p) ->
_GUI.loadScheme p, @, @host
@ -42,10 +44,13 @@ class BaseModel
if @dialog
@dialog.show()
return
if not _GUI.subwindows[d]
@error "Dialog #{d} not found"
return
@dialog = new _GUI.subwindows[d]()
if typeof d is "string"
if not _GUI.subwindows[d]
@error __("Dialog {0} not found", d)
return
@dialog = new _GUI.subwindows[d]()
else
@dialog = d
#@dialog.observable = riot.observable() unless @dialog
@dialog.parent = @
@dialog.handler = f

View File

@ -1,3 +1,36 @@
class FormatedString
constructor: (@fs, args) ->
@values = []
return unless args
@values[i] = args[i] for i in [0..args.length - 1]
toString: () ->
@__()
__: () ->
me = @
return @fs.l().replace /{(\d+)}/g, (match, number) ->
return if typeof me.values[number] != 'undefined' then me.values[number] else match
hash: () ->
@__().hash()
asBase64: () ->
@__().asBase64()
unescape: () ->
@__().unescape()
asUint8Array: () ->
@__().asUint8Array()
format: () ->
args = arguments
@values[i] = args[i] for i in [0..args.length - 1]
Object.defineProperty Object.prototype, '__',
value: () ->
return @toString()
enumerable: false
writable: true
String.prototype.hash = () ->
hash = 5381
i = this.length
@ -19,13 +52,41 @@ String.prototype.unescape = () ->
d = d.replace /\\f/g, "\f"
d = d.replace /\\r/g, "\r"
d
String.prototype.asUnit8Array = () ->
String.prototype.asUint8Array = () ->
bytes = []
for i in [0..(@length - 1)]
bytes.push @charCodeAt i
bytes = new Uint8Array(bytes)
return bytes
if not String.prototype.format
String.prototype.format = () ->
args = arguments
return @replace /{(\d+)}/g, (match, number) ->
return if typeof args[number] != 'undefined' then args[number] else match
String.prototype.f = () ->
args = arguments
return new FormatedString(@, args)
String.prototype.__ = () ->
match = @match(/^__\((.*)\)$/)
return match[1].l() if match
return @
String.prototype.l = () ->
_API = window.OS.API
_API.lang[@] = @ unless _API.lang[@]
return _API.lang[@]
# language directive
this.__ = () ->
_API = window.OS.API
args = arguments
return "Undefined" unless args.length > 0
d = args[0]
d.l()
return new FormatedString d, (args[i] for i in [1 .. args.length - 1])
Date.prototype.toString = () ->
dd = @getDate()
mm = @getMonth() + 1
@ -51,6 +112,7 @@ self.OS.API =
handler: {}
shared: {} # shared libraries
searchHandler:{}
lang:{}
#request a user data
mid: () ->
return _courrier.getMID()
@ -178,9 +240,9 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l
f() if f
, (e, s) ->
_courrier.oserror "Cannot load 3rd library at: #{l}", e, r
_courrier.oserror __("Cannot load 3rd library at: {0}", l), e, r
else
path = "os:///scripts/"
path = "os://scripts/"
js = "#{path}#{l}.js"
js.asFileHandler().onready (d) ->
_API.shared[l] = true
@ -196,7 +258,7 @@ self.OS.API =
_courrier.trigger "sharedlibraryloaded", l
f() if f
else
console.log l, "Library exist, no need to load"
console.log l, "Library exist, no need to load"
_courrier.trigger "sharedlibraryloaded", l
requires:(libs, f) ->
@ -214,7 +276,8 @@ self.OS.API =
_API.handler.packages {
command: "cache", args: { paths: (v for k, v of _OS.setting.system.pkgpaths) }
}, f
setting: (f) ->
_API.handler.setting f
search: (text) ->
r = []
@ -228,6 +291,18 @@ self.OS.API =
onsearch: (name, fn) ->
self.OS.API.searchHandler[name] = fn unless self.OS.API.searchHandler[name]
setLocale: (name, f) ->
path = "resources/languages/#{name}.json"
_API.get path, (d) ->
_OS.setting.system.locale = name
_API.lang = d
if f then f() else _courrier.trigger "systemlocalechange", name
, (e, s) ->
#_OS.setting.system.locale = "en_GB"
_courrier.oserror __("Language file {0} not found", path), e, s
f() if f
, "json"
throwe: (n) ->
err = undefined
try
@ -235,4 +310,33 @@ self.OS.API =
catch e
err = e
return "" if not err
return err
return err
# utilities functioncs
switcher: () ->
o = {}
p = {}
p[arguments[i]] = false for i in [0..arguments.length - 1 ]
Object.defineProperty o, "__p", {
enumerable: false,
value: p
}
fn = (o, v) ->
Object.defineProperty o, v, {
enumerable: true,
set: (value) ->
for k,l of @__p
@__p[k] = false
o.__p[v] = value
, get: () ->
return o.__p[v]
}
for k, v of o.__p
fn o, k
Object.defineProperty o, "selected", {
configurable: true,
enumerable: false,
get: () ->
for k,v of o.__p
return k if v
}
return o

View File

@ -1,3 +1,4 @@
'use strict'
#define the OS object
self = this
self.OS or=
@ -123,7 +124,7 @@ self.OS or=
exit: ->
#do clean up first
f() for n, f of _OS.cleanupHandlers
_API.handler.setting () ->
_API.handler.setting (r) ->
_API.handler.logout()
onexit: (n, f) ->
self.OS.cleanupHandlers[n] = f unless self.OS.cleanupHandlers[n]

View File

@ -5,7 +5,7 @@ class DB
_API.handler.dbquery "save", { table: @table, data: d }, f
delete: (c, f) ->
rq = { table: @table }
return ( _courrier.oserror "Unknown condition for delete command",
return ( _courrier.oserror __("VDB Unknown condition for delete command"),
(_API.throwe "OS.DB"), c ) unless c and c isnt ""
if isNaN c
rq.cond = c

View File

@ -9,7 +9,7 @@ self.OS.GUI =
META: {}
SYS_MENU: [
{
text: "Applications",
text: "__(Applications)",
child: [],
dataid: "sys-apps"
iconclass: "fa fa-adn",
@ -54,7 +54,7 @@ self.OS.GUI =
return
if not _GUI.subwindows[d]
ex = _API.throwe "Dialog"
return _courrier.oserror "Dialog #{d} not found", ex, null
return _courrier.oserror __("Dialog {0} not found", d), ex, null
_GUI.dialog = new _GUI.subwindows[d]()
_GUI.dialog.parent = _GUI
_GUI.dialog.handler = f
@ -73,10 +73,10 @@ self.OS.GUI =
return _PM.createProcess srv, _OS.APP[srv] if _OS.APP[srv]
(e, s) ->
_courrier.trigger "srvroutineready", srv
_courrier.osfail "Cannot read service script: #{srv} ", e, s
_courrier.osfail __("Cannot read service script: {0}", srv), e, s
appsByMime: (mime) ->
metas = ( v for k, v of _OS.setting.system.packages when v.app )
metas = ( v for k, v of _OS.setting.system.packages when v and v.app )
mimes = ( m.mimes for m in metas when m)
apps = []
# search app by mimes
@ -88,27 +88,27 @@ self.OS.GUI =
return false
return false
catch e
_courrier.osfail "Find app by mimes #{mime}", e, mime
_courrier.osfail __("Error find app by mimes {0}", mime), e, mime
( f m, i if m ) for m, i in mimes
return apps
appsWithServices: () ->
o = {}
o[k] = v for k, v of _OS.setting.system.packages when v.services and v.services.length > 0
o[k] = v for k, v of _OS.setting.system.packages when v and v.services and v.services.length > 0
o
openWith: (it) ->
return unless it
return _GUI.launch it.app if it.type is "app" and it.app
return _courrier.osinfo "Application#{it.text} is not executable" if it.type is "app"
return _courrier.osinfo __("Application {0} is not executable", it.text) if it.type is "app"
apps = _GUI.appsByMime ( if it.type is "dir" then "dir" else it.mime )
return _courrier.osinfo "No application available to open #{it.filename}" if apps.length is 0
return _courrier.osinfo __("No application available to open {0}", it.filename) if apps.length is 0
return _GUI.launch apps[0].app, [it.path] if apps.length is 1
list = ( { text: e.app, icon: e.icon, iconclass: e.iconclass } for e in apps )
_GUI.openDialog "SelectionDialog", ( d ) ->
_GUI.launch d.text, [it.path]
, "Open width", list
, __("Open with"), list
forceLaunch: (app, args) ->
console.log "This method is used for developing only, please use the launch method instead"
@ -118,7 +118,7 @@ self.OS.GUI =
_GUI.launch app, args
loadApp: (app, ok, err) ->
path = "os:///packages/#{app}"
path = "os://packages/#{app}"
path = _OS.setting.system.packages[app].path if _OS.setting.system.packages[app].path
js = path + "/main.js"
@ -161,7 +161,7 @@ self.OS.GUI =
app: app
onbtclick: () -> app.toggle()
# TODO: this path is not good, need to create a blob of it
data.icon = "#{_API.handler.get}/#{meta.path}/#{meta.icon}" if meta.icon
data.icon = "#{meta.path}/#{meta.icon}" if meta.icon
# TODO: add default app icon class in system setting
# so that it can be themed
data.iconclass = "fa fa-cogs" if (not meta.icon) and (not meta.iconclass)
@ -210,7 +210,15 @@ self.OS.GUI =
c = arr[1].toUpperCase()
return unless _GUI.shortcut[fnk]
_GUI.shortcut[fnk][c] = f
wallpaper: (obj) ->
if obj
_OS.setting.appearance.wp = obj
wp = _OS.setting.appearance.wp
$("body").css("background-image", "url(#{_API.handler.get}/#{wp.url})" )
.css("background-size", wp.size)
.css("background-repeat", wp.repeat)
initDM: ->
($ document).on 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', ()->
_GUI.fullscreen = not _GUI.fullscreen
@ -257,6 +265,7 @@ self.OS.GUI =
fp = _OS.setting.desktop.path.asFileHandler()
desktop[0].fetch = () ->
fn = () ->
fp = _OS.setting.desktop.path.asFileHandler()
fp.read (d) ->
return _courrier.osfail d.error, (_API.throwe "OS.VFS"), d.error if d.error
items = []
@ -305,8 +314,8 @@ self.OS.GUI =
desktop[0].set "selected", -1 if e.target is desktop[0]
($ "#sysdock").get(0).set "selectedApp", null
menu = [
{ text: "Open", dataid: "desktop-open" },
{ text: "Refresh", dataid: "desktop-refresh" }
{ text: __("Open"), dataid: "desktop-open" },
{ text: __("Refresh"), dataid: "desktop-refresh" }
]
menu = menu.concat ( v for k, v of _OS.setting.desktop.menu)
m.set "items", menu
@ -331,20 +340,21 @@ self.OS.GUI =
# mount it
riot.mount desktop
, (e, s) ->
alert "System fall: Cannot init desktop manager"
alert __("System fail: Cannot init desktop manager")
console.log s, e
refreshDesktop: () ->
($ "#desktop")[0].fetch()
refreshSystemMenu: () ->
_GUI.SYS_MENU.length = 1
_GUI.SYS_MENU[0].child.length = 0
_GUI.SYS_MENU[0].child.push v for k, v of _OS.setting.system.packages when (v and v.app)
_GUI.SYS_MENU.push v for k, v of _OS.setting.system.menu
_GUI.SYS_MENU.push
text: "Toggle Full screen",
text: "__(Toggle Full screen)",
dataid: "os-fullsize",
iconclass: "fa fa-tv"
_GUI.SYS_MENU.push
text: "Log out",
text: "__(Log out)",
dataid: "sys-logout",
iconclass: "fa fa-user-times"
buildSystemMenu: () ->
@ -361,7 +371,9 @@ self.OS.GUI =
($ "[data-id = 'os_menu']", "#syspanel")[0].set "items", menu
#console.log menu
mkdialog: (conf) ->
return new _GUI.BasicDialog conf.name, conf.layout
login: () ->
_OS.cleanup()
@ -378,20 +390,22 @@ self.OS.GUI =
($ "#txtpass").keyup (e) ->
($ "#btlogin").click() if e.which is 13
, (e, s) ->
alert "System fall: Cannot init login screen"
alert __("System fail: Cannot init login screen")
startAntOS: (conf) ->
# clean up things
_OS.cleanup()
# get setting from conf
_OS.systemSetting(conf)
_OS.systemSetting conf
#console.log _OS.setting
# load theme
_GUI.loadTheme _OS.setting.appearance.theme
# initDM
_GUI.initDM()
_GUI.wallpaper()
_courrier.observable.one "syspanelloaded", () ->
# TODO load packages list then build system menu
_courrier.observable.on "systemlocalechange", (name) ->
($ "#syspanel")[0].update()
_API.packages.cache (ret) ->
if ret.result
_API.packages.fetch (r) ->
@ -401,6 +415,7 @@ self.OS.GUI =
v.filename = k
v.type = "app"
v.mime = "antos/app"
v.icon = "#{v.path}/#{v.icon}" if v.icon
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
_OS.setting.system.packages = if r.result then r.result else
_GUI.refreshSystemMenu()
@ -409,4 +424,7 @@ self.OS.GUI =
# TODO: get services list from user setting
_GUI.pushServices (v for v in _OS.setting.system.startup.services)
(_GUI.launch a) for a in _OS.setting.system.startup.apps
#_GUI.launch "DummyApp"
#_GUI.launch "DummyApp"
# initDM
_API.setLocale _OS.setting.system.locale, () ->
_GUI.initDM()

View File

@ -10,36 +10,36 @@ self.OS.API.handler =
scandir: (p, c ) ->
path = "#{_REST}/fs/scandir"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to scan directory: #{p}", e, s
_courrier.osfail __("Fail to scan directory: {0}", p), e, s
mkdir: (p, c ) ->
path = "#{_REST}/fs/mkdir"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to create directory: #{p}", e, s
_courrier.osfail __("Fail to create directory: {0}", p), e, s
sharefile: (p, pub , c) ->
path = "#{_REST}/fs/publish"
_API.post path, { path: p , publish: pub }, c, (e, s) ->
_courrier.osfail "Fail to publish file: #{p}", e, s
_courrier.osfail __("Fail to publish file: {0}", p), e, s
fileinfo: (p, c) ->
path = "#{_REST}/fs/fileinfo"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to get file metadata: #{p}", e, s
_courrier.osfail __("Fail to get file meta data: {0}", p), e, s
readfile: (p, c, t) ->
path = "#{_REST}/fs/get/"
_API.get path + p, c, (e, s) ->
_courrier.osfail "Fail to read file: #{p}", e, s
_courrier.osfail __("Fail to read file: {0}", p), e, s
, t
move: (s, d, c) ->
path = "#{_REST}/fs/move"
_API.post path, { src: s, dest: d }, c, (e, s) ->
_courrier.osfail "Fail to move file: #{s} -> #{d}", e, s
_courrier.osfail __("Fail to move file: {0} -> {1}", s, d), e, s
delete: (p , c) ->
path = "#{_REST}/fs/delete"
_API.post path, { path: p }, c, (e, s) ->
_courrier.osfail "Fail to delete: #{p}", e, s
_courrier.osfail __("Fail to delete: {0}", p), e, s
fileblob: (p, c) ->
path = "#{_REST}/fs/get/"
@ -49,44 +49,46 @@ self.OS.API.handler =
packages: (d, c) ->
path = "#{_REST}/system/packages"
_API.post path, d, c, (e, s) ->
_courrier.osfail "Fail to #{d.command} package", e, s
_courrier.osfail __("Fail to {0} package", d.command), e, s
upload: (d, c) ->
path = "#{_REST}/fs/upload"
_API.upload path, d, c, (e, s) ->
_courrier.osfail "Fail to upload file to: #{d}", e, s
_courrier.osfail __("Fail to upload file to: {0}", d), e, s
write: (p, d , c) ->
path = "#{_REST}/fs/write"
_API.post path, { path: p, data: d }, c, (e, s) ->
_courrier.osfail "Fail to write to file: #{p}", e, s
_courrier.osfail __("Fail to write to file: {0}", p), e, s
scanapp: (p, c ) ->
path = "#{_REST}/system/application"
auth: (c) ->
p = "#{_REST}/system/auth"
_API.post p, {}, c, () ->
alert "Resource not found: #{p}"
_API.post p, {}, c, (e, s) ->
console.log e, s
alert __("Resource not found: {0}", p)
login: (d, c) ->
p = "#{_REST}/system/login"
_API.post p, d, c, () ->
alert "Resource not found: #{p}"
alert __("Resource not found: {0}", p)
logout: () ->
p = "#{_REST}/system/logout"
_API.post p, {}, (d) ->
_OS.boot()
, () ->
alert "Resource not found #{p}"
alert __("Resource not found: {0}", p)
setting: (f) ->
p = "#{_REST}/system/settings"
_API.post p, _OS.setting, (d) ->
_courrier.oserror "Cannot save system setting", d.error if d.error
f() if f
_courrier.oserror __("Cannot save system setting"), d.error if d.error
f(d) if f
, (e, s) ->
_courrier.osfail "Fail to make request: #{p}", e, s
f() if f
m = __("Fail to make request: {0}", p)
_courrier.osfail m , e, s
f({ error: m }) if f
dbquery: (cmd, d, c) ->
path = "#{_REST}/db/#{cmd}"
_API.post path, d, c, (e, s) ->
_courrier.osfail "Fail to query data from database: #{path}", e, s
_courrier.osfail __("Fail to query data from database: {0}", path), e, s

View File

@ -0,0 +1,217 @@
{
"About":"About",
"About: {0}":"About: {0}",
"Add category":"Add category",
"Add repository":"Add repository",
"Address":"Address",
"Alive (ms)":"Alive (ms)",
"Application installed":"Application installed",
"Application {0} is not executable":"Application {0} is not executable",
"Application":"Application",
"Applications":"Applications",
"April":"April",
"August":"August",
"Authentication":"Authentication",
"Cancel":"Cancel",
"Cannot Edit category":"Cannot Edit category",
"Cannot add new category":"Cannot add new category",
"Cannot create {0}":"Cannot create {0}",
"Cannot delete all content of: {0} [{1}]":"Cannot delete all content of: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Cannot delete the category: {0} [{1}]",
"Cannot delete the section: {0}":"Cannot delete the section: {0}",
"Cannot delete: {0}":"Cannot delete: {0}",
"Cannot down load the app {0}":"Cannot down load the app {0}",
"Cannot export file for embedding to text":"Cannot export file for embedding to text",
"Cannot fetch CV categories":"Cannot fetch CV categories",
"Cannot fetch the entry content":"Cannot fetch the entry content",
"Cannot fetch user data":"Cannot fetch user data",
"Cannot install {0}":"Cannot install {0}",
"Cannot load 3rd library at: {0}":"Cannot load 3rd library at: {0}",
"Cannot move section":"Cannot move section",
"Cannot read service script: {0}":"Cannot read service script: {0}",
"Cannot render the PDF file":"Cannot render the PDF file",
"Cannot save blog: {0}":"Cannot save blog: {0}",
"Cannot save section: {0}":"Cannot save section: {0}",
"Cannot save system setting":"Cannot save system setting",
"Cannot save user data":"Cannot save user data",
"Cannot share file: {0}":"Cannot share file: {0}",
"Cannot uninstall package: {0}":"Cannot uninstall package: {0}",
"Categories":"Categories",
"Clear all":"Clear all",
"Close tab":"Close tab",
"Close without saving ?":"Close without saving ?",
"Close":"Close",
"Copy not yet implemented":"Copy not yet implemented",
"Copy":"Copy",
"Created: {0}":"Created: {0}",
"Cut":"Cut",
"December":"December",
"Delete a post":"Delete a post",
"Delete category":"Delete category",
"Delete section":"Delete section",
"Delete":"Delete",
"Desktop":"Desktop",
"Dialog {0} not found":"Dialog {0} not found",
"Do you really want to delete this post ?":"Do you really want to delete this post ?",
"Do you really want to delete: {0}?":"Do you really want to delete: {0}?",
"Download":"Download",
"Edit category":"Edit category",
"Edit repository":"Edit repository",
"Edit":"Edit",
"Email":"Email",
"Error find app by mimes {0}":"Error find app by mimes {0}",
"Error reading package meta data: {0}":"Error reading package meta data: {0}",
"Error saving file {0}":"Error saving file {0}",
"Exit":"Exit",
"Fail to create directory: {0}":"Fail to create directory: {0}",
"Fail to create {0}: {1}":"Fail to create {0}: {1}",
"Fail to delete {0}: {1}":"Fail to delete {0}: {1}",
"Fail to delete: {0}":"Fail to delete: {0}",
"Fail to fetch packages list from: {0}":"Fail to fetch packages list from: {0}",
"Fail to get file meta data: {0}":"Fail to get file meta data: {0}",
"Fail to make request: {0}":"Fail to make request: {0}",
"Fail to move file: {0} -> {1}":"Fail to move file: {0} -> {1}",
"Fail to paste: {0}":"Fail to paste: {0}",
"Fail to publish file: {0}":"Fail to publish file: {0}",
"Fail to query data from database: {0}":"Fail to query data from database: {0}",
"Fail to read file: {0}":"Fail to read file: {0}",
"Fail to rename to {0}: {1}":"Fail to rename to {0}: {1}",
"Fail to scan directory: {0}":"Fail to scan directory: {0}",
"Fail to upload file to: {0}":"Fail to upload file to: {0}",
"Fail to upload to {0}: {1}":"Fail to upload to {0}: {1}",
"Fail to write to file: {0}":"Fail to write to file: {0}",
"Fail to {0} package":"Fail to {0} package",
"February":"February",
"File name":"File name",
"File not found {0}":"File not found {0}",
"File {0} copied":"File {0} copied",
"File {0} cut":"File {0} cut",
"File":"File",
"Folder name":"Folder name",
"Format : [name] url":"Format : [name] url",
"Found {0} sections":"Found {0} sections",
"Fri":"Fri",
"From":"From",
"Full name must be entered":"Full name must be entered",
"Full name":"Full name",
"Google Drive":"Google Drive",
"Hidden files":"Hidden files",
"Home":"Home",
"Icon view":"Icon view",
"Ignore all {0} unsaved files ?":"Ignore all {0} unsaved files ?",
"Install":"Install",
"Invalid package: Meta data file not found":"Invalid package: Meta data file not found",
"January":"January",
"July":"July",
"June":"June",
"Kill process":"Kill process",
"Language file {0} not found":"Language file {0} not found",
"Launch":"Launch",
"List view":"List view",
"Location":"Location",
"Log out":"Log out",
"Logout":"Logout",
"March":"March",
"May":"May",
"Mime type {0} is not supported":"Mime type {0} is not supported",
"Modify section entry":"Modify section entry",
"Mon":"Mon",
"Move to":"Move to",
"Name":"Name",
"Navigation bar":"Navigation bar",
"New file":"New file",
"New folder":"New folder",
"New section entry for {0}":"New section entry for {0}",
"New":"New",
"No application available to open {0}":"No application available to open {0}",
"No post found: {0}":"No post found: {0}",
"No":"No",
"November":"November",
"OS":"OS",
"October":"October",
"Ok":"Ok",
"Only {0} could be selected":"Only {0} could be selected",
"Open file":"Open file",
"Open with":"Open with",
"Open":"Open",
"Options":"Options",
"Package uninstalled":"Package uninstalled",
"Parent can not be the category itself":"Parent can not be the category itself",
"Paste":"Paste",
"Phone":"Phone",
"Pid":"Pid",
"Please enter category name":"Please enter category name",
"Please enter tags":"Please enter tags",
"Please insert a title in the text: beginning with heading":"Please insert a title in the text: beginning with heading",
"Please select a category":"Please select a category",
"Please select a date":"Please select a date",
"Please select a file":"Please select a file",
"Please select a parent category":"Please select a parent category",
"Please select a section to edit":"Please select a section to edit",
"Please select a section to move":"Please select a section to move",
"Preview":"Preview",
"Properties":"Properties",
"Quit without saving ?":"Quit without saving ?",
"Quit":"Quit",
"Read more":"Read more",
"Refresh":"Refresh",
"Rename":"Rename",
"Repositories":"Repositories",
"Resource not found {0}":"Resource not found {0}",
"Resource not found: {0}":"Resource not found: {0}",
"Row {0}, col {1}, lines: {2}":"Row {0}, col {1}, lines: {2}",
"Sat":"Sat",
"Save as":"Save as",
"Save":"Save",
"Section list is empty, please add one":"Section list is empty, please add one",
"Select image file":"Select image file",
"Selected: {0} ({1} bytes)":"Selected: {0} ({1} bytes)",
"September":"September",
"Service":"Service",
"Share file":"Share file",
"Shared url: {0}":"Shared url: {0}",
"Shared":"Shared",
"Short biblio":"Short biblio",
"Sidebar":"Sidebar",
"Size":"Size",
"Subtitle":"Subtitle",
"Sun":"Sun",
"System fail: Cannot init desktop manager":"System fail: Cannot init desktop manager",
"System fail: Cannot init login screen":"System fail: Cannot init login screen",
"Tags":"Tags",
"This feature is not implemented yet":"This feature is not implemented yet",
"Thu":"Thu",
"Title or content must not be blank":"Title or content must not be blank",
"Title":"Title",
"Toggle Full screen":"Toggle Full screen",
"Tree view":"Tree view",
"Tue":"Tue",
"Type":"Type",
"Uninstall : {0}?":"Uninstall : {0}?",
"Uninstall":"Uninstall",
"Unknown API setting for {0}":"Unknown API setting for {0}",
"Updated: {0}":"Updated: {0}",
"Upload":"Upload",
"Url":"Url",
"User abort the authentication":"User abort the authentication",
"User data updated":"User data updated",
"VDB Unknown condition for delete command":"VDB Unknown condition for delete command",
"VFS Cannot encode file: {0}":"VFS Cannot encode file: {0}",
"VFS cannot create : {0}":"VFS cannot create : {0}",
"VFS cannot delete : {0}":"VFS cannot delete : {0}",
"VFS cannot download file : {0}":"VFS cannot download file : {0}",
"VFS cannot get meta data for {0}":"VFS cannot get meta data for {0}",
"VFS cannot init {0}: {1}":"VFS cannot init {0}: {1}",
"VFS cannot move : {0}":"VFS cannot move : {0}",
"VFS cannot read : {0}":"VFS cannot read : {0}",
"VFS cannot save : {0}":"VFS cannot save : {0}",
"VFS cannot write : {0}":"VFS cannot write : {0}",
"VFS unknown action: {0}":"VFS unknown action: {0}",
"VFS unknown handler: {0}":"VFS unknown handler: {0}",
"View":"View",
"Wed":"Wed",
"Would you like to login to {0}?":"Would you like to login to {0}?",
"Wrong format: it should be [name] url":"Wrong format: it should be [name] url",
"Yes":"Yes",
"{0} is not a directory":"{0} is not a directory"
}

View File

@ -0,0 +1,217 @@
{
"About":"About",
"About: {0}":"About: {0}",
"Add category":"Add category",
"Add repository":"Add repository",
"Address":"Address",
"Alive (ms)":"Alive (ms)",
"Application installed":"Application installed",
"Application {0} is not executable":"Application {0} is not executable",
"Application":"Application",
"Applications":"Applications",
"April":"April",
"August":"August",
"Authentication":"Authentication",
"Cancel":"Cancel",
"Cannot Edit category":"Cannot Edit category",
"Cannot add new category":"Cannot add new category",
"Cannot create {0}":"Cannot create {0}",
"Cannot delete all content of: {0} [{1}]":"Cannot delete all content of: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Cannot delete the category: {0} [{1}]",
"Cannot delete the section: {0}":"Cannot delete the section: {0}",
"Cannot delete: {0}":"Cannot delete: {0}",
"Cannot down load the app {0}":"Cannot down load the app {0}",
"Cannot export file for embedding to text":"Cannot export file for embedding to text",
"Cannot fetch CV categories":"Cannot fetch CV categories",
"Cannot fetch the entry content":"Cannot fetch the entry content",
"Cannot fetch user data":"Cannot fetch user data",
"Cannot install {0}":"Cannot install {0}",
"Cannot load 3rd library at: {0}":"Cannot load 3rd library at: {0}",
"Cannot move section":"Cannot move section",
"Cannot read service script: {0}":"Cannot read service script: {0}",
"Cannot render the PDF file":"Cannot render the PDF file",
"Cannot save blog: {0}":"Cannot save blog: {0}",
"Cannot save section: {0}":"Cannot save section: {0}",
"Cannot save system setting":"Cannot save system setting",
"Cannot save user data":"Cannot save user data",
"Cannot share file: {0}":"Cannot share file: {0}",
"Cannot uninstall package: {0}":"Cannot uninstall package: {0}",
"Categories":"Categories",
"Clear all":"Clear all",
"Close tab":"Close tab",
"Close without saving ?":"Close without saving ?",
"Close":"Close",
"Copy not yet implemented":"Copy not yet implemented",
"Copy":"Copy",
"Created: {0}":"Created: {0}",
"Cut":"Cut",
"December":"December",
"Delete a post":"Delete a post",
"Delete category":"Delete category",
"Delete section":"Delete section",
"Delete":"Delete",
"Desktop":"Desktop",
"Dialog {0} not found":"Dialog {0} not found",
"Do you really want to delete this post ?":"Do you really want to delete this post ?",
"Do you really want to delete: {0}?":"Do you really want to delete: {0}?",
"Download":"Download",
"Edit category":"Edit category",
"Edit repository":"Edit repository",
"Edit":"Edit",
"Email":"Email",
"Error find app by mimes {0}":"Error find app by mimes {0}",
"Error reading package meta data: {0}":"Error reading package meta data: {0}",
"Error saving file {0}":"Error saving file {0}",
"Exit":"Exit",
"Fail to create directory: {0}":"Fail to create directory: {0}",
"Fail to create {0}: {1}":"Fail to create {0}: {1}",
"Fail to delete {0}: {1}":"Fail to delete {0}: {1}",
"Fail to delete: {0}":"Fail to delete: {0}",
"Fail to fetch packages list from: {0}":"Fail to fetch packages list from: {0}",
"Fail to get file meta data: {0}":"Fail to get file meta data: {0}",
"Fail to make request: {0}":"Fail to make request: {0}",
"Fail to move file: {0} -> {1}":"Fail to move file: {0} -> {1}",
"Fail to paste: {0}":"Fail to paste: {0}",
"Fail to publish file: {0}":"Fail to publish file: {0}",
"Fail to query data from database: {0}":"Fail to query data from database: {0}",
"Fail to read file: {0}":"Fail to read file: {0}",
"Fail to rename to {0}: {1}":"Fail to rename to {0}: {1}",
"Fail to scan directory: {0}":"Fail to scan directory: {0}",
"Fail to upload file to: {0}":"Fail to upload file to: {0}",
"Fail to upload to {0}: {1}":"Fail to upload to {0}: {1}",
"Fail to write to file: {0}":"Fail to write to file: {0}",
"Fail to {0} package":"Fail to {0} package",
"February":"February",
"File name":"File name",
"File not found {0}":"File not found {0}",
"File {0} copied":"File {0} copied",
"File {0} cut":"File {0} cut",
"File":"File",
"Folder name":"Folder name",
"Format : [name] url":"Format : [name] url",
"Found {0} sections":"Found {0} sections",
"Fri":"Fri",
"From":"From",
"Full name must be entered":"Full name must be entered",
"Full name":"Full name",
"Google Drive":"Google Drive",
"Hidden files":"Hidden files",
"Home":"Home",
"Icon view":"Icon view",
"Ignore all {0} unsaved files ?":"Ignore all {0} unsaved files ?",
"Install":"Install",
"Invalid package: Meta data file not found":"Invalid package: Meta data file not found",
"January":"January",
"July":"July",
"June":"June",
"Kill process":"Kill process",
"Language file {0} not found":"Language file {0} not found",
"Launch":"Launch",
"List view":"List view",
"Location":"Location",
"Log out":"Log out",
"Logout":"Logout",
"March":"March",
"May":"May",
"Mime type {0} is not supported":"Mime type {0} is not supported",
"Modify section entry":"Modify section entry",
"Mon":"Mon",
"Move to":"Move to",
"Name":"Name",
"Navigation bar":"Navigation bar",
"New file":"New file",
"New folder":"New folder",
"New section entry for {0}":"New section entry for {0}",
"New":"New",
"No application available to open {0}":"No application available to open {0}",
"No post found: {0}":"No post found: {0}",
"No":"No",
"November":"November",
"OS":"OS",
"October":"October",
"Ok":"Ok",
"Only {0} could be selected":"Only {0} could be selected",
"Open file":"Open file",
"Open with":"Open with",
"Open":"Open",
"Options":"Options",
"Package uninstalled":"Package uninstalled",
"Parent can not be the category itself":"Parent can not be the category itself",
"Paste":"Paste",
"Phone":"Phone",
"Pid":"Pid",
"Please enter category name":"Please enter category name",
"Please enter tags":"Please enter tags",
"Please insert a title in the text: beginning with heading":"Please insert a title in the text: beginning with heading",
"Please select a category":"Please select a category",
"Please select a date":"Please select a date",
"Please select a file":"Please select a file",
"Please select a parent category":"Please select a parent category",
"Please select a section to edit":"Please select a section to edit",
"Please select a section to move":"Please select a section to move",
"Preview":"Preview",
"Properties":"Properties",
"Quit without saving ?":"Quit without saving ?",
"Quit":"Quit",
"Read more":"Read more",
"Refresh":"Refresh",
"Rename":"Rename",
"Repositories":"Repositories",
"Resource not found {0}":"Resource not found {0}",
"Resource not found: {0}":"Resource not found: {0}",
"Row {0}, col {1}, lines: {2}":"Row {0}, col {1}, lines: {2}",
"Sat":"Sat",
"Save as":"Save as",
"Save":"Save",
"Section list is empty, please add one":"Section list is empty, please add one",
"Select image file":"Select image file",
"Selected: {0} ({1} bytes)":"Selected: {0} ({1} bytes)",
"September":"September",
"Service":"Service",
"Share file":"Share file",
"Shared url: {0}":"Shared url: {0}",
"Shared":"Shared",
"Short biblio":"Short biblio",
"Sidebar":"Sidebar",
"Size":"Size",
"Subtitle":"Subtitle",
"Sun":"Sun",
"System fail: Cannot init desktop manager":"System fail: Cannot init desktop manager",
"System fail: Cannot init login screen":"System fail: Cannot init login screen",
"Tags":"Tags",
"This feature is not implemented yet":"This feature is not implemented yet",
"Thu":"Thu",
"Title or content must not be blank":"Title or content must not be blank",
"Title":"Title",
"Toggle Full screen":"Toggle Full screen",
"Tree view":"Tree view",
"Tue":"Tue",
"Type":"Type",
"Uninstall : {0}?":"Uninstall : {0}?",
"Uninstall":"Uninstall",
"Unknown API setting for {0}":"Unknown API setting for {0}",
"Updated: {0}":"Updated: {0}",
"Upload":"Upload",
"Url":"Url",
"User abort the authentication":"User abort the authentication",
"User data updated":"User data updated",
"VDB Unknown condition for delete command":"VDB Unknown condition for delete command",
"VFS Cannot encode file: {0}":"VFS Cannot encode file: {0}",
"VFS cannot create : {0}":"VFS cannot create : {0}",
"VFS cannot delete : {0}":"VFS cannot delete : {0}",
"VFS cannot download file : {0}":"VFS cannot download file : {0}",
"VFS cannot get meta data for {0}":"VFS cannot get meta data for {0}",
"VFS cannot init {0}: {1}":"VFS cannot init {0}: {1}",
"VFS cannot move : {0}":"VFS cannot move : {0}",
"VFS cannot read : {0}":"VFS cannot read : {0}",
"VFS cannot save : {0}":"VFS cannot save : {0}",
"VFS cannot write : {0}":"VFS cannot write : {0}",
"VFS unknown action: {0}":"VFS unknown action: {0}",
"VFS unknown handler: {0}":"VFS unknown handler: {0}",
"View":"View",
"Wed":"Wed",
"Would you like to login to {0}?":"Would you like to login to {0}?",
"Wrong format: it should be [name] url":"Wrong format: it should be [name] url",
"Yes":"Yes",
"{0} is not a directory":"{0} is not a directory"
}

View File

@ -0,0 +1,248 @@
{
"About":"À propos de",
"About: {0}":"À propos de: {0}",
"Add category":"Ajouter une catégorie",
"Add repository":"Ajouter un dépôt",
"Address":"Adresse",
"Alive (ms)":"Actif (ms)",
"Application installed":"Application installée",
"Application {0} is not executable":"L'application {0} n'est pas exécutable",
"Application":"Application",
"Applications":"Applications",
"Authentication":"Authentification",
"Cancel":"Annuler",
"Cannot Edit category":"Impossible d'éditer la catégorie",
"Cannot add new category":"Impossible d'ajouter une nouvelle catégorie",
"Cannot create {0}":"Impossible de créer {0}",
"Cannot delete all content of: {0} [{1}]":"Impossible de supprimer tout le contenu de: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Impossible de supprimer la catégorie: {0} [{1}]",
"Cannot delete the section: {0}":"Impossible de supprimer la section: {0}",
"Cannot delete: {0}":"Impossible de supprimer: {0}",
"Cannot down load the app {0}":"Impossible de télécharger l'application {0}",
"Cannot export file for embedding to text":"Impossible d'exporter le fichier pour l'intégrer au texte",
"Cannot fetch CV categories":"Impossible d'extraire les catégories de CV",
"Cannot fetch the entry content":"Impossible d'extraire le contenu",
"Cannot fetch user data":"Impossible d'extraire les données utilisateur",
"Cannot install {0}":"Impossible d'installer {0}",
"Cannot load 3rd library at: {0}":"Impossible de charger la bibliothèque à: {0}",
"Cannot move section":"Impossible de déplacer la section",
"Cannot read service script: {0}":"Impossible de lire le script de service: {0}",
"Cannot render the PDF file":"Impossible de rendre le fichier PDF",
"Cannot save blog: {0}":"Impossible d'enregistrer le blog: {0}",
"Cannot save section: {0}":"Impossible d'enregistrer la section: {0}",
"Cannot save system setting":"Impossible d'enregistrer les paramètres du système",
"Cannot save user data":"Impossible d'enregistrer les données utilisateur",
"Cannot share file: {0}":"Impossible de partager le fichier: {0}",
"Cannot uninstall package: {0}":"Impossible de désinstaller le package: {0}",
"Categories":"Catégories",
"Clear all":"Tout effacer",
"Close tab":"Fermer l'onglet",
"Close without saving ?":"Fermer sans enregistrer?",
"Close":"Fermer",
"Copy not yet implemented":"Copie non encore implémentée",
"Copy":"Copier",
"Created: {0}":"Créé: {0}",
"Cut":"Couper",
"Delete a post":"Supprimer le text",
"Delete category":"Supprimer la catégorie",
"Delete section":"Supprimer la section",
"Delete":"Supprimer",
"Desktop":"Bureau",
"Dialog {0} not found":"La boîte de dialogue {0} n'a pas été trouvée",
"Do you really want to delete this post ?":"Voulez-vous vraiment supprimer ce texte ?",
"Do you really want to delete: {0}?":"Voulez-vous vraiment supprimer: {0}?",
"Download":"Télécharger",
"Edit category":"Modifier la catégorie",
"Edit repository":"Modifier le dépôt",
"Edit":"Modifier",
"Email":"Email",
"Error find app by mimes {0}":"Erreur lors de la recherche d'application par mimes {0}",
"Error reading package meta data: {0}":"Erreur lors de la lecture des métadonnées du package: {0}",
"Error saving file {0}":"Erreur lors de l'enregistrement du fichier {0}",
"Exit":"Quitter",
"Fail to create directory: {0}":"Impossible de créer le répertoire: {0}",
"Fail to create {0}: {1}":"Échec de la création de {0}: {1}",
"Fail to delete {0}: {1}":"Échec de la suppression de {0}: {1}",
"Fail to delete: {0}":"Échec de la suppression: {0}",
"Fail to fetch packages list from: {0}":"Impossible d'extraire la liste des paquets de: {0}",
"Fail to get file meta data: {0}":"Échec d'obtention des métadonnées de fichier: {0}",
"Fail to make request: {0}":"Echec de la demande: {0}",
"Fail to move file: {0} -> {1}":"Échec du déplacement du fichier: {0} -> {1}",
"Fail to paste: {0}":"Impossible de coller: {0}",
"Fail to publish file: {0}":"Échec de la publication du fichier: {0}",
"Fail to query data from database: {0}":"Impossible d'interroger les données de la base de données: {0}",
"Fail to read file: {0}":"Impossible de lire le fichier: {0}",
"Fail to rename to {0}: {1}":"Impossible de renommer en {0}: {1}",
"Fail to scan directory: {0}":"Échec de l'analyse du répertoire: {0}",
"Fail to upload file to: {0}":"Impossible de télécharger le fichier vers: {0}",
"Fail to upload to {0}: {1}":"Impossible de télécharger vers {0}: {1}",
"Fail to write to file: {0}":"Échec de l'écriture dans le fichier: {0}",
"Fail to {0} package":"Échec du {0} paquet",
"File name":"Nom de fichier",
"File not found {0}":"Fichier introuvable {0}",
"File {0} copied":"Fichier {0} copié",
"File {0} cut":"Fichier {0} coupé",
"File":"Fichier",
"Folder name":"Nom de dossier",
"Format : [name] url":"Format: [nom] url",
"Found {0} sections":"{0} sections trouvées",
"From":"De",
"Full name must be entered":"Le nom complet doit être entré",
"Full name":"Nom complet",
"Google Drive":"Google Drive",
"Hidden files":"Fichiers cachés",
"Home":"Accueil",
"Icon view":"Vue d'icône",
"Ignore all {0} unsaved files ?":"Ignorer tous les {0} fichiers non enregistrés?",
"Install":"Installer",
"Invalid package: Meta data file not found":"Paquet invalide: Fichier de métadonnées non trouvé",
"Kill process":"Tuer le processus",
"Language file {0} not found":"Fichier de langue {0} introuvable",
"Launch":"Lancer",
"List view":"Vue de liste",
"Location":"Localisation",
"Log out":"Déconnecter",
"Logout":"Déconnecter",
"Mime type {0} is not supported":"Le type MIME {0} n'est pas supporté",
"Modify section entry":"Modifier le texte",
"Move to":"Déplacer vers",
"Name":"Nom",
"Navigation bar":"Barre de navigation",
"New file":"Nouveau fichier",
"New folder":"Nouveau dossier",
"New section entry for {0}":"Nouvelle entrée de section pour {0}",
"New":"Nouveau",
"No application available to open {0}":"Aucune application disponible pour ouvrir {0}",
"No post found: {0}":"Aucun texte trouvé: {0}",
"No":"Non",
"OS":"OS",
"Ok":"Oui",
"Only {0} could be selected":"Seul {0} peut être sélectionné",
"Open file":"Ouvrir un fichier",
"Open with":"Ouvrir avec",
"Open":"Ouvrir",
"Options":"Options",
"Package uninstalled":"Package désinstallé",
"Parent can not be the category itself":"Parent ne peut pas être la catégorie elle-même",
"Paste":"Coller",
"Phone":"Phone",
"Pid":"Pid",
"Please enter category name":"Veuillez entrer le nom de la catégorie",
"Please enter tags":"Veuillez entrer les tags",
"Please insert a title in the text: beginning with heading":"Veuillez insérer un titre dans le texte: en commençant par le heading",
"Please select a category":"Veuillez sélectionner une catégorie",
"Please select a date":"Veuillez sélectionner une date",
"Please select a file":"Veuillez sélectionner un fichier",
"Please select a parent category":"Veuillez sélectionner une catégorie parente",
"Please select a section to edit":"Veuillez sélectionner une section à modifier",
"Please select a section to move":"Veuillez sélectionner une section à déplacer",
"Preview":"Aperçu",
"Properties":"Propriétés",
"Quit without saving ?":"Quitter sans sauvegarder ?",
"Quit":"Quitter",
"Read more":"Lire la suite",
"Refresh":"Rafraîchir",
"Rename":"Renommer",
"Repositories":"Dépôts",
"Resource not found {0}":"Ressource non trouvée {0}",
"Resource not found: {0}":"Ressource non trouvée: {0}",
"Row {0}, col {1}, lines: {2}":"Range {0}, col {1}, lignes: {2}",
"Save as":"Enregistrer sous",
"Save":"sauvegarder",
"Section list is empty, please add one":"La liste des sections est vide, veuillez en ajouter une",
"Select image file":"Sélectionnez le fichier image",
"Service":"Service",
"Share file":"Partagez le fichier",
"Shared url: {0}":"URL partagée: {0}",
"Shared":"partagé",
"Short biblio":"Biblio court",
"Sidebar":"Barre latérale",
"Subtitle":"Sous-titre",
"System fail: Cannot init desktop manager":"Échec du système: impossible de démarrer le gestionnaire de bureau",
"System fail: Cannot init login screen":"Echec du système: Impossible de se connecter à l'écran de connexion",
"Tags":"Tags",
"This feature is not implemented yet":"Cette fonctionnalité n'est pas encore implémentée",
"Title or content must not be blank":"Le titre ou le contenu ne doit pas être vide",
"Title":"Titre",
"Toggle Full screen":"Basculer en plein écran",
"Tree view":"Vue de l'arbre",
"Type":"Type",
"Uninstall : {0}?":"Désinstaller: {0}?",
"Uninstall":"Désinstaller",
"Unknown API setting for {0}":"Paramètre d'API inconnu pour {0}",
"Updated: {0}":"Actualisé: {0}",
"Upload":"Télécharger",
"Url":"Url",
"User abort the authentication":"L'utilisateur annule l'authentification",
"User data updated":"Données utilisateur mises à jour",
"VDB Unknown condition for delete command":"VDB Condition inconnue pour la commande de suppression",
"VFS Cannot encode file: {0}":"VFS Impossible de coder le fichier: {0}",
"VFS cannot create : {0}":"VFS ne peut pas créer: {0}",
"VFS cannot delete : {0}":"VFS ne peut pas supprimer: {0}",
"VFS cannot download file : {0}":"VFS ne peut pas télécharger le fichier: {0}",
"VFS cannot get meta data for {0}":"VFS ne peut pas obtenir de métadonnées pour {0}",
"VFS cannot init {0}: {1}":"VFS ne peut pas init {0}: {1}",
"VFS cannot move : {0}":"VFS ne peut pas déplacer: {0}",
"VFS cannot read : {0}":"VFS ne peut pas lire: {0}",
"VFS cannot save : {0}":"VFS ne peut pas enregistrer: {0}",
"VFS cannot write : {0}":"VFS ne peut pas écrire: {0}",
"VFS unknown action: {0}":"Action inconnue VFS: {0}",
"VFS unknown handler: {0}":"Gestionnaire inconnu VFS: {0}",
"View":"Vue",
"Would you like to login to {0}?":"Voulez-vous vous connecter à {0}?",
"Wrong format: it should be [name] url":"Mauvais format: il devrait être [nom] url",
"Yes":"Oui",
"{0} is not a directory":"{0} n'est pas un répertoire"
,
"April":"Avril",
"August":"août",
"December":"Décembre",
"February":"Février",
"Fri":"Ven",
"January":"Janvier",
"July":"Juillet",
"June":"Juin",
"March":"Mars",
"May":"Mai",
"Mon":"Lun",
"November":"Novembre",
"October":"Octobre",
"Sat":"Sam",
"Selected: {0} ({1} bytes)":"Sélectionné: {0} ({1} octets)",
"September":"Septembre",
"Size":"Taille",
"Sun":"Dim",
"Thu":"Jeu",
"Tue":"Mar",
"Wed":"Mer"
,
"Add application":"Ajouter une application",
"Add mount point":"Ajouter un point de montage",
"Add service":"Ajouter un service",
"Appearance":"Apparence",
"Cannot fetch system locales: {0}":"Impossible d'extraire les paramètres régionaux du système: {0}",
"Cannot read wallpaper list from {0}":"Impossible de lire la liste des fonds d'écran à partir de {0}",
"Cannot save system setting: {0}":"Impossible d'enregistrer le paramètre système: {0}",
"Desktop path":"Chemin du bureau",
"Edit mount point":"Modifier le point de montage",
"Languages":"Langues",
"Local packages path":"Chemin d'accès aux packages locaux",
"Mount points":"Points de montage",
"Path":"Chemin",
"Please enter mount point name":"Veuillez entrer le nom du point de montage",
"Please select a directory":"Veuillez sélectionner un répertoire",
"Please select an entry":"Veuillez sélectionner une entrée",
"Remove: {0}?":"Supprimer: {0}?",
"Remove":"Supprimer",
"Select a directory":"Sélectionnez un répertoire",
"Startup applications":"Applications de démarrage",
"Startup services":"Services de démarrage",
"Startup":"Démarrage",
"System locale":"Paramètres régionaux du système",
"System setting saved":"Paramètre système enregistré",
"Theme":"Thème",
"VFS":"VFS",
"Wallpaper":"Fond d'écran"
}

View File

@ -0,0 +1,219 @@
{
"About":"About",
"About: {0}":"About: {0}",
"Add category":"Add category",
"Add repository":"Add repository",
"Address":"Address",
"Alive (ms)":"Alive (ms)",
"Application installed":"Application installed",
"Application {0} is not executable":"Application {0} is not executable",
"Application":"Application",
"Applications":"Applications",
"Authentication":"Authentication",
"Cancel":"Cancel",
"Cannot Edit category":"Cannot Edit category",
"Cannot add new category":"Cannot add new category",
"Cannot create {0}":"Cannot create {0}",
"Cannot delete all content of: {0} [{1}]":"Cannot delete all content of: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Cannot delete the category: {0} [{1}]",
"Cannot delete the section: {0}":"Cannot delete the section: {0}",
"Cannot delete: {0}":"Cannot delete: {0}",
"Cannot down load the app {0}":"Cannot down load the app {0}",
"Cannot export file for embedding to text":"Cannot export file for embedding to text",
"Cannot fetch CV categories":"Cannot fetch CV categories",
"Cannot fetch the entry content":"Cannot fetch the entry content",
"Cannot fetch user data":"Cannot fetch user data",
"Cannot install {0}":"Cannot install {0}",
"Cannot load 3rd library at: {0}":"Cannot load 3rd library at: {0}",
"Cannot move section":"Cannot move section",
"Cannot read service script: {0}":"Cannot read service script: {0}",
"Cannot render the PDF file":"Cannot render the PDF file",
"Cannot save blog: {0}":"Cannot save blog: {0}",
"Cannot save section: {0}":"Cannot save section: {0}",
"Cannot save system setting":"Cannot save system setting",
"Cannot save user data":"Cannot save user data",
"Cannot share file: {0}":"Cannot share file: {0}",
"Cannot uninstall package: {0}":"Cannot uninstall package: {0}",
"Categories":"Categories",
"Clear all":"Clear all",
"Close tab":"Close tab",
"Close without saving ?":"Close without saving ?",
"Close":"Close",
"Copy not yet implemented":"Copy not yet implemented",
"Copy":"Copy",
"Created: {0}":"Created: {0}",
"Cut":"Cut",
"Delete a post":"Delete a post",
"Delete category":"Delete category",
"Delete section":"Delete section",
"Delete":"Delete",
"Desktop":"Desktop",
"Dialog {0} not found":"Dialog {0} not found",
"Do you really want to delete this post ?":"Do you really want to delete this post ?",
"Do you really want to delete: {0}?":"Do you really want to delete: {0}?",
"Download":"Download",
"Edit category":"Edit category",
"Edit repository":"Edit repository",
"Edit":"Edit",
"Email":"Email",
"Error find app by mimes {0}":"Error find app by mimes {0}",
"Error reading package meta data: {0}":"Error reading package meta data: {0}",
"Error saving file {0}":"Error saving file {0}",
"Exit":"Exit",
"Fail to create directory: {0}":"Fail to create directory: {0}",
"Fail to create {0}: {1}":"Fail to create {0}: {1}",
"Fail to delete {0}: {1}":"Fail to delete {0}: {1}",
"Fail to delete: {0}":"Fail to delete: {0}",
"Fail to fetch packages list from: {0}":"Fail to fetch packages list from: {0}",
"Fail to get file meta data: {0}":"Fail to get file meta data: {0}",
"Fail to make request: {0}":"Fail to make request: {0}",
"Fail to move file: {0} -> {1}":"Fail to move file: {0} -> {1}",
"Fail to paste: {0}":"Fail to paste: {0}",
"Fail to publish file: {0}":"Fail to publish file: {0}",
"Fail to query data from database: {0}":"Fail to query data from database: {0}",
"Fail to read file: {0}":"Fail to read file: {0}",
"Fail to rename to {0}: {1}":"Fail to rename to {0}: {1}",
"Fail to scan directory: {0}":"Fail to scan directory: {0}",
"Fail to upload file to: {0}":"Fail to upload file to: {0}",
"Fail to upload to {0}: {1}":"Fail to upload to {0}: {1}",
"Fail to write to file: {0}":"Fail to write to file: {0}",
"Fail to {0} package":"Fail to {0} package",
"File name":"File name",
"File not found {0}":"File not found {0}",
"File {0} copied":"File {0} copied",
"File {0} cut":"File {0} cut",
"File":"File",
"Folder name":"Folder name",
"Format : [name] url":"Format : [name] url",
"Found {0} sections":"Found {0} sections",
"From":"From",
"Full name must be entered":"Full name must be entered",
"Full name":"Full name",
"Google Drive":"Google Drive",
"Hidden files":"Hidden files",
"Home":"Home",
"Icon view":"Icon view",
"Ignore all {0} unsaved files ?":"Ignore all {0} unsaved files ?",
"Install":"Install",
"Invalid package: Meta data file not found":"Invalid package: Meta data file not found",
"Kill process":"Kill process",
"Language file {0} not found":"Language file {0} not found",
"Launch":"Launch",
"List view":"List view",
"Location":"Location",
"Log out":"Log out",
"Logout":"Logout",
"Mime type {0} is not supported":"Mime type {0} is not supported",
"Modify section entry":"Modify section entry",
"Move to":"Move to",
"Name":"Name",
"Navigation bar":"Navigation bar",
"New file":"New file",
"New folder":"New folder",
"New section entry for {0}":"New section entry for {0}",
"New":"New",
"No application available to open {0}":"No application available to open {0}",
"No post found: {0}":"No post found: {0}",
"No":"No",
"OS":"OS",
"Ok":"Ok",
"Only {0} could be selected":"Only {0} could be selected",
"Open file":"Open file",
"Open with":"Open with",
"Open":"Open",
"Options":"Options",
"Package uninstalled":"Package uninstalled",
"Parent can not be the category itself":"Parent can not be the category itself",
"Paste":"Paste",
"Phone":"Phone",
"Pid":"Pid",
"Please enter category name":"Please enter category name",
"Please enter tags":"Please enter tags",
"Please insert a title in the text: beginning with heading":"Please insert a title in the text: beginning with heading",
"Please select a category":"Please select a category",
"Please select a date":"Please select a date",
"Please select a file":"Please select a file",
"Please select a parent category":"Please select a parent category",
"Please select a section to edit":"Please select a section to edit",
"Please select a section to move":"Please select a section to move",
"Preview":"Preview",
"Properties":"Properties",
"Quit without saving ?":"Quit without saving ?",
"Quit":"Quit",
"Read more":"Read more",
"Refresh":"Refresh",
"Rename":"Rename",
"Repositories":"Repositories",
"Resource not found {0}":"Resource not found {0}",
"Resource not found: {0}":"Resource not found: {0}",
"Row {0}, col {1}, lines: {2}":"Row {0}, col {1}, lines: {2}",
"Save as":"Save as",
"Save":"Save",
"Section list is empty, please add one":"Section list is empty, please add one",
"Select image file":"Select image file",
"Service":"Service",
"Share file":"Share file",
"Shared url: {0}":"Shared url: {0}",
"Shared":"Shared",
"Short biblio":"Short biblio",
"Sidebar":"Sidebar",
"Subtitle":"Subtitle",
"System fail: Cannot init desktop manager":"System fail: Cannot init desktop manager",
"System fail: Cannot init login screen":"System fail: Cannot init login screen",
"Tags":"Tags",
"This feature is not implemented yet":"This feature is not implemented yet",
"Title or content must not be blank":"Title or content must not be blank",
"Title":"Title",
"Toggle Full screen":"Toggle Full screen",
"Tree view":"Tree view",
"Type":"Type",
"Uninstall : {0}?":"Uninstall : {0}?",
"Uninstall":"Uninstall",
"Unknown API setting for {0}":"Unknown API setting for {0}",
"Updated: {0}":"Updated: {0}",
"Upload":"Upload",
"Url":"Url",
"User abort the authentication":"User abort the authentication",
"User data updated":"User data updated",
"VDB Unknown condition for delete command":"VDB Unknown condition for delete command",
"VFS Cannot encode file: {0}":"VFS Cannot encode file: {0}",
"VFS cannot create : {0}":"VFS cannot create : {0}",
"VFS cannot delete : {0}":"VFS cannot delete : {0}",
"VFS cannot download file : {0}":"VFS cannot download file : {0}",
"VFS cannot get meta data for {0}":"VFS cannot get meta data for {0}",
"VFS cannot init {0}: {1}":"VFS cannot init {0}: {1}",
"VFS cannot move : {0}":"VFS cannot move : {0}",
"VFS cannot read : {0}":"VFS cannot read : {0}",
"VFS cannot save : {0}":"VFS cannot save : {0}",
"VFS cannot write : {0}":"VFS cannot write : {0}",
"VFS unknown action: {0}":"VFS unknown action: {0}",
"VFS unknown handler: {0}":"VFS unknown handler: {0}",
"View":"View",
"Would you like to login to {0}?":"Would you like to login to {0}?",
"Wrong format: it should be [name] url":"Wrong format: it should be [name] url",
"Yes":"Yes",
"{0} is not a directory":"{0} is not a directory"
,
"April":"April",
"August":"August",
"December":"December",
"February":"February",
"Fri":"Fri",
"January":"January",
"July":"July",
"June":"June",
"March":"March",
"May":"May",
"Mon":"Mon",
"November":"November",
"October":"October",
"Sat":"Sat",
"Selected: {0} ({1} bytes)":"Selected: {0} ({1} bytes)",
"September":"September",
"Size":"Size",
"Sun":"Sun",
"Thu":"Thu",
"Tue":"Tue",
"Wed":"Wed"
}

43
src/core/languages/gen.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash
ord() {
LC_CTYPE=C printf '%d' "'$1"
}
grep --include=\*.{coffee,tag} -roh "$1" -e '__("[^"]*"' | while read -r line ; do
SUBSTRING=$(echo $line| cut -d'"' -f 2)
if test -f "$2" && [ ! -z "$(grep -F "\"$SUBSTRING\":" "$2")" ]
then
echo "Ignore: $SUBSTRING"
else
echo -e "\t\"$SUBSTRING\":\"$SUBSTRING\"," >> "tmp.json"
fi
done
grep --include=\*.{coffee,html,tag} -roh "$1" -e '\"__\([^\"]*\)\"' | while read -r line; do
len=$(( ${#line} - 6 ))
#echo $len
SUBSTRING=${line:4:len}
#echo $SUBSTRING
if test -f "$2" && [ ! -z "$(grep -F "\"$SUBSTRING\":" "$2")" ]
then
echo "Ignore: $SUBSTRING"
else
echo -e "\t\"$SUBSTRING\":\"$SUBSTRING\"," >> "tmp.json"
fi
done
sort tmp.json > tmp1.json
awk '!a[$0]++' "tmp1.json" > tmp.json
sed '$ s/.$//' tmp.json > tmp1.json
# remove duplicate entry
if test -f $2
then
cp $2 "$2.old"
sed '$ s/.$//' $2 > tmp.json
cat tmp.json > $2
echo "," >> $2
cat tmp1.json >> $2
echo "}" >> "$2"
else
echo "{"> "$2"
cat tmp1.json >> "$2"
echo "}" >> "$2"
fi
rm tmp.json tmp1.json

View File

@ -0,0 +1,258 @@
{
"About":"Thông tin",
"About: {0}":"Thông tin: {0}",
"Add category":"Thêm danh mục",
"Add repository":"Thêm kho ứng dụng",
"Address":"Địa chỉ",
"Alive (ms)":"Hoạt động (ms)",
"Application installed":"Ứng dụng đã được cà đặt",
"Application {0} is not executable":"Ứng dụng {0} không thực thi được",
"Application":"Ứng dụng",
"Applications":"Các ứng dụng",
"Authentication":"Xác thực",
"Cancel":"Huỷ",
"Cannot Edit category":"Không thể sửa danh mục",
"Cannot add new category":"Không thể tạo mới danh mục",
"Cannot create {0}":"Không thể tạo {0}",
"Cannot delete all content of: {0} [{1}]":"Không thể xoá hết nội dung của: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Không thể xoá danh mục: {0} [{1}]",
"Cannot delete the section: {0}":"Không thể xoá mục: {0}",
"Cannot delete: {0}":"Không thể xoá: {0}",
"Cannot down load the app {0}":"Không thể tải xuống ứng dụng {0}",
"Cannot export file for embedding to text":"Không thể xuất bản file để chèn vào text",
"Cannot fetch CV categories":"Không thể lấy danh mục CV",
"Cannot fetch the entry content":"Không thể truy vấn nội dung của mục",
"Cannot fetch user data":"Không thể truy vấn thông tin người dùng",
"Cannot install {0}":"Không thể cài đặt {0}",
"Cannot load 3rd library at: {0}":"Không thể tải về thư viện bên thứ 3: {0}",
"Cannot move section":"Không thể di chuyển mục",
"Cannot read service script: {0}":"Không thể tải về script của dịch vụ: {0}",
"Cannot render the PDF file":"Không thể hiển thị file PDF",
"Cannot save blog: {0}":"Không thể lưu blog: {0}",
"Cannot save section: {0}":"Không thể lưu mục: {0}",
"Cannot save system setting":"Không thể lưu cài đặt hệ thống",
"Cannot save user data":"Không thể lưu thông tin người dùng",
"Cannot share file: {0}":"Không thể chia sẻ file: {0}",
"Cannot uninstall package: {0}":"Không thể gỡ cài đặt ứng dụng: {0}",
"Categories":"Các danh mục",
"Clear all":"Xoá tất cả",
"Close tab":"Đóng tab",
"Close without saving ?":"Đóng không cần lưu ?",
"Close":"Đóng",
"Copy not yet implemented":"Chức năng copy chưa được cài đặt",
"Copy":"Copy",
"Created: {0}":"Tạo: {0}",
"Cut":"Cắt",
"Delete a post":"Xoá bài",
"Delete category":"Xoá danh mục",
"Delete section":"Xoá mục",
"Delete":"Xoá",
"Desktop":"Desktop",
"Dialog {0} not found":"Không tìm thấy hộp thoại {0}",
"Do you really want to delete this post ?":"Bạn muốn xoá bài này ?",
"Do you really want to delete: {0}?":"Bạn muốn xoá: {0}?",
"Download":"Tải về",
"Edit category":"Sửa danh mục",
"Edit repository":"Sửa kho ứng dụng",
"Edit":"Sửa",
"Email":"Email",
"Error find app by mimes {0}":"Lỗi khi tìm app bằng mime {0}",
"Error reading package meta data: {0}":"Lỗi khi đọc thông tin ứng dụng: {0}",
"Error saving file {0}":"Lỗi khi lưu file {0}",
"Exit":"Thoát",
"Fail to create directory: {0}":"Lỗi khi tạo folder: {0}",
"Fail to create {0}: {1}":"Lỗi khi tạo {0}: {1}",
"Fail to delete {0}: {1}":"Lỗi khi xoá {0}: {1}",
"Fail to delete: {0}":"Lỗi khi xoá: {0}",
"Fail to fetch packages list from: {0}":"Lỗi khi tải về danh sách ứng dụng từ: {0}",
"Fail to get file meta data: {0}":"Lỗi truy vấn thông tin file: {0}",
"Fail to make request: {0}":"Lỗi truy vấn: {0}",
"Fail to move file: {0} -> {1}":"Lỗi di chuyển file: {0} -> {1}",
"Fail to paste: {0}":"Lỗi khi dán: {0}",
"Fail to publish file: {0}":"Lỗi khi xuất bản file: {0}",
"Fail to query data from database: {0}":"Lỗi truy vấn cơ sở dữ liệu: {0}",
"Fail to read file: {0}":"Lỗi đọc file: {0}",
"Fail to rename to {0}: {1}":"Lỗi khi đổi tên file {0}: {1}",
"Fail to scan directory: {0}":"Lỗi khi quét thư mục: {0}",
"Fail to upload file to: {0}":"Lỗi khi tải file lên: {0}",
"Fail to upload to {0}: {1}":"Lỗi khi tải file lên {0}: {1}",
"Fail to write to file: {0}":"Lỗi khi ghi file: {0}",
"Fail to {0} package":"Lỗi {0} ứng dụng",
"File name":"Tên file",
"File not found {0}":"Không tìm thấy file {0}",
"File {0} copied":"Đã copy file {0}",
"File {0} cut":"Đã cắt file {0}",
"File":"File",
"Folder name":"Tên thư mục",
"Format : [name] url":"Định dạng : [name] url",
"Found {0} sections":"Tìm thấy {0} mục",
"From":"Từ",
"Full name must be entered":"Vui lòng điền họ và tên",
"Full name":"Họ và tên",
"Google Drive":"Google Drive",
"Hidden files":"File ẩn",
"Home":"Home",
"Icon view":"Xêm theo icon",
"Ignore all {0} unsaved files ?":"Bỏ qua {0} file chưa lưu ?",
"Install":"Cài đặt",
"Invalid package: Meta data file not found":"Ứng dụng không hợp lệ: không tìm thấy metadata",
"Kill process":"Đóng process",
"Language file {0} not found":"Không tìm thấy ngôn ngữ {0}",
"Launch":"Khởi chạy",
"List view":"Xem theo list",
"Location":"Vị trí",
"Log out":"Đăng xuất",
"Logout":"Đăng xuất",
"Mime type {0} is not supported":"Mime type {0} không được hổ trợ",
"Modify section entry":"Sửa mục",
"Move to":"Di chuyển vào",
"Name":"Tên",
"Navigation bar":"Thanh điều hướng",
"New file":"File mới",
"New folder":"Thư mục mới",
"New section entry for {0}":"Thêm mới mục trong {0}",
"New":"Tạo mới",
"No application available to open {0}":"Không tìm thấy ứng dụng dể đọc {0}",
"No post found: {0}":"Không tìm thấy bài: {0}",
"No":"Không",
"OS":"OS",
"Ok":"Có",
"Only {0} could be selected":"Chỉ file với mine {0} mới được chọn",
"Open file":"Mở file",
"Open with":"Mở với",
"Open":"Mở",
"Options":"Tuỳ chọn",
"Package uninstalled":"Đã gỡ bỏ ứng dụng",
"Parent can not be the category itself":"Danh mục cha không được trùng với danh mục hiện tại",
"Paste":"Dán",
"Phone":"Số điện thoại",
"Pid":"Pid",
"Please enter category name":"Vui lòng nhập tên danh mục",
"Please enter tags":"Vui lòng nhập tags",
"Please insert a title in the text: beginning with heading":"Vuil lòng nhập tiêu đề: bắt đầu bài bằng heading",
"Please select a category":"Vui lòng chọn danh mục",
"Please select a date":"Vui lòng chọn ngày",
"Please select a file":"Vui lòng chọn file",
"Please select a parent category":"Vui lòng chọn danh much cha",
"Please select a section to edit":"Vui lòng chọn mục để sửa",
"Please select a section to move":"Vuil lòng chọn mục để di chuyển",
"Preview":"Preview",
"Properties":"Thông tin",
"Quit without saving ?":"Thoát mà không lưu ?",
"Quit":"Thoát",
"Read more":"Đọc thêm",
"Refresh":"Làm mới",
"Rename":"Đổi tên",
"Repositories":"Các kho ứng dụng",
"Resource not found {0}":"Không tìm thấy tài nguyên {0}",
"Resource not found: {0}":"Không tìm thấy tài nguyên: {0}",
"Row {0}, col {1}, lines: {2}":"Hàng {0}, cột {1}, dòng: {2}",
"Save as":"Lưu như",
"Save":"Lưu",
"Section list is empty, please add one":"Danh sách mục rỗng, vui lòng tạo mới",
"Select image file":"Chọn file ảnh",
"Service":"Dịch vụ",
"Share file":"Chia sẻ",
"Shared url: {0}":"Liên kết chia sẻ: {0}",
"Shared":"Đã chia sẻ",
"Short biblio":"Tiểu sử ngắn",
"Sidebar":"Sidebar",
"Subtitle":"Tiêu đề con",
"System fail: Cannot init desktop manager":"Lỗi hệ thống: không thể khởi chạy trình quản lý desktop",
"System fail: Cannot init login screen":"Lỗi hệ thống: không thể khởi chạy màn hình đăng nhập",
"Tags":"Tags",
"This feature is not implemented yet":"Chức năng này chưa được cài đặt",
"Title or content must not be blank":"Tiêu đề hoặc nội dụng không được để trống",
"Title":"Tiêu đề",
"Toggle Full screen":"Bật/tắt toàn màn hình",
"Tree view":"Xem theo cây",
"Type":"Loại",
"Uninstall : {0}?":"Gỡ cài đặt : {0}?",
"Uninstall":"Gỡ cài đặt",
"Unknown API setting for {0}":"Không tìm thấy cài đặt API của {0}",
"Updated: {0}":"Đã cập nhật: {0}",
"Upload":"Tải lên",
"Url":"Url",
"User abort the authentication":"Người dùng huỷ xác thực",
"User data updated":"Thông tin người dùng đã được cập nhật",
"VDB Unknown condition for delete command":"VDB không rõ điều kiện cho lệnh xoá",
"VFS Cannot encode file: {0}":"VFS Không thể mã hoá file: {0}",
"VFS cannot create : {0}":"VFS không thể tạo : {0}",
"VFS cannot delete : {0}":"VFS không thể xoá : {0}",
"VFS cannot download file : {0}":"VFS không thể tải về : {0}",
"VFS cannot get meta data for {0}":"VFS không thể truy vấn thông tin của {0}",
"VFS cannot init {0}: {1}":"VFS không thể khởi động {0}: {1}",
"VFS cannot move : {0}":"VFS không thể di chuyển : {0}",
"VFS cannot read : {0}":"VFS không thể đọc : {0}",
"VFS cannot save : {0}":"VFS không thể lưu : {0}",
"VFS cannot write : {0}":"VFS không thể viết : {0}",
"VFS unknown action: {0}":"VFS không rõ hành động : {0}",
"VFS unknown handler: {0}":"VFS không rõ trình xữ lý: {0}",
"View":"Xem",
"Would you like to login to {0}?":"Bạn có muốn đăng nhập vào {0}?",
"Wrong format: it should be [name] url":"Sai định dạng: định dạng hợp lệ [name] url",
"Yes":"Có",
"{0} is not a directory":"{0} không phải là thư mục"
,
"April":"Tháng 4",
"August":"Tháng 8",
"December":"Tháng 12",
"February":"Tháng hai",
"Fri":"Sáu",
"January":"Tháng một",
"July":"Tháng 7",
"June":"Tháng 6",
"March":"Tháng 3",
"May":"Tháng 5",
"Mon":"Hai",
"November":"Tháng 11",
"October":"Tháng 10",
"Sat":"Bảy",
"Selected: {0} ({1} bytes)":"Đã chọn: {0} ({1} bytes)",
"September":"Tháng 9",
"Size":"Kích cỡ",
"Sun":"CN",
"Thu":"Năm",
"Tue":"Ba",
"Wed":"Tư"
,
"Add":"Thêm",
"Cannot read wallpaper list from {0}":"Không thể truy vấn danh sách wallpaper {0}",
"Theme":"Chủ đề",
"Wallpaper":"Hình nền"
,
"Appearance":"Giao diện",
"Cannot fetch system locales: {0}":"Không thể truy vấn danh sách ngôn ngữ: {0}",
"Cannot save system setting: {0}":"Không thể lưu cài đặt hệ thống: {0}",
"Desktop path":"Đường dẫn đến desktop",
"Languages":"Ngôn ngữ",
"Local packages path":"Đường dẫn đến ứng dụng riêng",
"Mount points":"Điểm truy cập nhanh",
"Path":"Đường dẫn",
"Please enter mount point name":"Vui lòng nhập điểm truy cập",
"Please select a directory":"Vui lòng chọn một thư mục",
"Remove: {0}?":"xoá: {0}?",
"Remove":"xoá",
"Select a directory":"Chọn một thư mục",
"System locale":"Ngôn ngữ",
"System setting saved":"Đã lưu cài đặt hệ thống",
"VFS":"VFS"
,
"Add mount point":"Thêm điểm truy cập",
"Edit mount point":"Sửa điểm truy cập"
,
"Services":"Dịch vụ",
"Startup":"Khởi chạy"
,
"Add application":"Thêm ứng dụng",
"Add service":"Thêm dịch vụ",
"Please select an entry":"Vui lòng chọn 1 mục từ danh sách",
"Startup applications":"Ứng dụng khởi chạy",
"Startup services":"Dịch vụ khởi chạy"
}

View File

@ -0,0 +1,251 @@
{
"About":"Thông tin",
"About: {0}":"Thông tin: {0}",
"Add category":"Thêm danh mục",
"Add repository":"Thêm kho ứng dụng",
"Address":"Địa chỉ",
"Alive (ms)":"Hoạt động (ms)",
"Application installed":"Ứng dụng đã được cà đặt",
"Application {0} is not executable":"Ứng dụng {0} không thực thi được",
"Application":"Ứng dụng",
"Applications":"Các ứng dụng",
"Authentication":"Xác thực",
"Cancel":"Huỷ",
"Cannot Edit category":"Không thể sửa danh mục",
"Cannot add new category":"Không thể tạo mới danh mục",
"Cannot create {0}":"Không thể tạo {0}",
"Cannot delete all content of: {0} [{1}]":"Không thể xoá hết nội dung của: {0} [{1}]",
"Cannot delete the category: {0} [{1}]":"Không thể xoá danh mục: {0} [{1}]",
"Cannot delete the section: {0}":"Không thể xoá mục: {0}",
"Cannot delete: {0}":"Không thể xoá: {0}",
"Cannot down load the app {0}":"Không thể tải xuống ứng dụng {0}",
"Cannot export file for embedding to text":"Không thể xuất bản file để chèn vào text",
"Cannot fetch CV categories":"Không thể lấy danh mục CV",
"Cannot fetch the entry content":"Không thể truy vấn nội dung của mục",
"Cannot fetch user data":"Không thể truy vấn thông tin người dùng",
"Cannot install {0}":"Không thể cài đặt {0}",
"Cannot load 3rd library at: {0}":"Không thể tải về thư viện bên thứ 3: {0}",
"Cannot move section":"Không thể di chuyển mục",
"Cannot read service script: {0}":"Không thể tải về script của dịch vụ: {0}",
"Cannot render the PDF file":"Không thể hiển thị file PDF",
"Cannot save blog: {0}":"Không thể lưu blog: {0}",
"Cannot save section: {0}":"Không thể lưu mục: {0}",
"Cannot save system setting":"Không thể lưu cài đặt hệ thống",
"Cannot save user data":"Không thể lưu thông tin người dùng",
"Cannot share file: {0}":"Không thể chia sẻ file: {0}",
"Cannot uninstall package: {0}":"Không thể gỡ cài đặt ứng dụng: {0}",
"Categories":"Các danh mục",
"Clear all":"Xoá tất cả",
"Close tab":"Đóng tab",
"Close without saving ?":"Đóng không cần lưu ?",
"Close":"Đóng",
"Copy not yet implemented":"Chức năng copy chưa được cài đặt",
"Copy":"Copy",
"Created: {0}":"Tạo: {0}",
"Cut":"Cắt",
"Delete a post":"Xoá bài",
"Delete category":"Xoá danh mục",
"Delete section":"Xoá mục",
"Delete":"Xoá",
"Desktop":"Desktop",
"Dialog {0} not found":"Không tìm thấy hộp thoại {0}",
"Do you really want to delete this post ?":"Bạn muốn xoá bài này ?",
"Do you really want to delete: {0}?":"Bạn muốn xoá: {0}?",
"Download":"Tải về",
"Edit category":"Sửa danh mục",
"Edit repository":"Sửa kho ứng dụng",
"Edit":"Sửa",
"Email":"Email",
"Error find app by mimes {0}":"Lỗi khi tìm app bằng mime {0}",
"Error reading package meta data: {0}":"Lỗi khi đọc thông tin ứng dụng: {0}",
"Error saving file {0}":"Lỗi khi lưu file {0}",
"Exit":"Thoát",
"Fail to create directory: {0}":"Lỗi khi tạo folder: {0}",
"Fail to create {0}: {1}":"Lỗi khi tạo {0}: {1}",
"Fail to delete {0}: {1}":"Lỗi khi xoá {0}: {1}",
"Fail to delete: {0}":"Lỗi khi xoá: {0}",
"Fail to fetch packages list from: {0}":"Lỗi khi tải về danh sách ứng dụng từ: {0}",
"Fail to get file meta data: {0}":"Lỗi truy vấn thông tin file: {0}",
"Fail to make request: {0}":"Lỗi truy vấn: {0}",
"Fail to move file: {0} -> {1}":"Lỗi di chuyển file: {0} -> {1}",
"Fail to paste: {0}":"Lỗi khi dán: {0}",
"Fail to publish file: {0}":"Lỗi khi xuất bản file: {0}",
"Fail to query data from database: {0}":"Lỗi truy vấn cơ sở dữ liệu: {0}",
"Fail to read file: {0}":"Lỗi đọc file: {0}",
"Fail to rename to {0}: {1}":"Lỗi khi đổi tên file {0}: {1}",
"Fail to scan directory: {0}":"Lỗi khi quét thư mục: {0}",
"Fail to upload file to: {0}":"Lỗi khi tải file lên: {0}",
"Fail to upload to {0}: {1}":"Lỗi khi tải file lên {0}: {1}",
"Fail to write to file: {0}":"Lỗi khi ghi file: {0}",
"Fail to {0} package":"Lỗi {0} ứng dụng",
"File name":"Tên file",
"File not found {0}":"Không tìm thấy file {0}",
"File {0} copied":"Đã copy file {0}",
"File {0} cut":"Đã cắt file {0}",
"File":"File",
"Folder name":"Tên thư mục",
"Format : [name] url":"Định dạng : [name] url",
"Found {0} sections":"Tìm thấy {0} mục",
"From":"Từ",
"Full name must be entered":"Vui lòng điền họ và tên",
"Full name":"Họ và tên",
"Google Drive":"Google Drive",
"Hidden files":"File ẩn",
"Home":"Home",
"Icon view":"Xêm theo icon",
"Ignore all {0} unsaved files ?":"Bỏ qua {0} file chưa lưu ?",
"Install":"Cài đặt",
"Invalid package: Meta data file not found":"Ứng dụng không hợp lệ: không tìm thấy metadata",
"Kill process":"Đóng process",
"Language file {0} not found":"Không tìm thấy ngôn ngữ {0}",
"Launch":"Khởi chạy",
"List view":"Xem theo list",
"Location":"Vị trí",
"Log out":"Đăng xuất",
"Logout":"Đăng xuất",
"Mime type {0} is not supported":"Mime type {0} không được hổ trợ",
"Modify section entry":"Sửa mục",
"Move to":"Di chuyển vào",
"Name":"Tên",
"Navigation bar":"Thanh điều hướng",
"New file":"File mới",
"New folder":"Thư mục mới",
"New section entry for {0}":"Thêm mới mục trong {0}",
"New":"Tạo mới",
"No application available to open {0}":"Không tìm thấy ứng dụng dể đọc {0}",
"No post found: {0}":"Không tìm thấy bài: {0}",
"No":"Không",
"OS":"OS",
"Ok":"Có",
"Only {0} could be selected":"Chỉ file với mine {0} mới được chọn",
"Open file":"Mở file",
"Open with":"Mở với",
"Open":"Mở",
"Options":"Tuỳ chọn",
"Package uninstalled":"Đã gỡ bỏ ứng dụng",
"Parent can not be the category itself":"Danh mục cha không được trùng với danh mục hiện tại",
"Paste":"Dán",
"Phone":"Số điện thoại",
"Pid":"Pid",
"Please enter category name":"Vui lòng nhập tên danh mục",
"Please enter tags":"Vui lòng nhập tags",
"Please insert a title in the text: beginning with heading":"Vuil lòng nhập tiêu đề: bắt đầu bài bằng heading",
"Please select a category":"Vui lòng chọn danh mục",
"Please select a date":"Vui lòng chọn ngày",
"Please select a file":"Vui lòng chọn file",
"Please select a parent category":"Vui lòng chọn danh much cha",
"Please select a section to edit":"Vui lòng chọn mục để sửa",
"Please select a section to move":"Vuil lòng chọn mục để di chuyển",
"Preview":"Preview",
"Properties":"Thông tin",
"Quit without saving ?":"Thoát mà không lưu ?",
"Quit":"Thoát",
"Read more":"Đọc thêm",
"Refresh":"Làm mới",
"Rename":"Đổi tên",
"Repositories":"Các kho ứng dụng",
"Resource not found {0}":"Không tìm thấy tài nguyên {0}",
"Resource not found: {0}":"Không tìm thấy tài nguyên: {0}",
"Row {0}, col {1}, lines: {2}":"Hàng {0}, cột {1}, dòng: {2}",
"Save as":"Lưu như",
"Save":"Lưu",
"Section list is empty, please add one":"Danh sách mục rỗng, vui lòng tạo mới",
"Select image file":"Chọn file ảnh",
"Service":"Dịch vụ",
"Share file":"Chia sẻ",
"Shared url: {0}":"Liên kết chia sẻ: {0}",
"Shared":"Đã chia sẻ",
"Short biblio":"Tiểu sử ngắn",
"Sidebar":"Sidebar",
"Subtitle":"Tiêu đề con",
"System fail: Cannot init desktop manager":"Lỗi hệ thống: không thể khởi chạy trình quản lý desktop",
"System fail: Cannot init login screen":"Lỗi hệ thống: không thể khởi chạy màn hình đăng nhập",
"Tags":"Tags",
"This feature is not implemented yet":"Chức năng này chưa được cài đặt",
"Title or content must not be blank":"Tiêu đề hoặc nội dụng không được để trống",
"Title":"Tiêu đề",
"Toggle Full screen":"Bật/tắt toàn màn hình",
"Tree view":"Xem theo cây",
"Type":"Loại",
"Uninstall : {0}?":"Gỡ cài đặt : {0}?",
"Uninstall":"Gỡ cài đặt",
"Unknown API setting for {0}":"Không tìm thấy cài đặt API của {0}",
"Updated: {0}":"Đã cập nhật: {0}",
"Upload":"Tải lên",
"Url":"Url",
"User abort the authentication":"Người dùng huỷ xác thực",
"User data updated":"Thông tin người dùng đã được cập nhật",
"VDB Unknown condition for delete command":"VDB không rõ điều kiện cho lệnh xoá",
"VFS Cannot encode file: {0}":"VFS Không thể mã hoá file: {0}",
"VFS cannot create : {0}":"VFS không thể tạo : {0}",
"VFS cannot delete : {0}":"VFS không thể xoá : {0}",
"VFS cannot download file : {0}":"VFS không thể tải về : {0}",
"VFS cannot get meta data for {0}":"VFS không thể truy vấn thông tin của {0}",
"VFS cannot init {0}: {1}":"VFS không thể khởi động {0}: {1}",
"VFS cannot move : {0}":"VFS không thể di chuyển : {0}",
"VFS cannot read : {0}":"VFS không thể đọc : {0}",
"VFS cannot save : {0}":"VFS không thể lưu : {0}",
"VFS cannot write : {0}":"VFS không thể viết : {0}",
"VFS unknown action: {0}":"VFS không rõ hành động : {0}",
"VFS unknown handler: {0}":"VFS không rõ trình xữ lý: {0}",
"View":"Xem",
"Would you like to login to {0}?":"Bạn có muốn đăng nhập vào {0}?",
"Wrong format: it should be [name] url":"Sai định dạng: định dạng hợp lệ [name] url",
"Yes":"Có",
"{0} is not a directory":"{0} không phải là thư mục"
,
"April":"Tháng 4",
"August":"Tháng 8",
"December":"Tháng 12",
"February":"Tháng hai",
"Fri":"Sáu",
"January":"Tháng một",
"July":"Tháng 7",
"June":"Tháng 6",
"March":"Tháng 3",
"May":"Tháng 5",
"Mon":"Hai",
"November":"Tháng 11",
"October":"Tháng 10",
"Sat":"Bảy",
"Selected: {0} ({1} bytes)":"Đã chọn: {0} ({1} bytes)",
"September":"Tháng 9",
"Size":"Kích cỡ",
"Sun":"CN",
"Thu":"Năm",
"Tue":"Ba",
"Wed":"Tư"
,
"Add":"Thêm",
"Cannot read wallpaper list from {0}":"Không thể truy vấn danh sách wallpaper {0}",
"Theme":"Chủ đề",
"Wallpaper":"Hình nền"
,
"Appearance":"Giao diện",
"Cannot fetch system locales: {0}":"Không thể truy vấn danh sách ngôn ngữ: {0}",
"Cannot save system setting: {0}":"Không thể lưu cài đặt hệ thống: {0}",
"Desktop path":"Đường dẫn đến desktop",
"Languages":"Ngôn ngữ",
"Local packages path":"Đường dẫn đến ứng dụng riêng",
"Mount points":"Điểm truy cập nhanh",
"Path":"Đường dẫn",
"Please enter mount point name":"Vui lòng nhập điểm truy cập",
"Please select a directory":"Vui lòng chọn một thư mục",
"Remove: {0}?":"xoá: {0}?",
"Remove":"xoá",
"Select a directory":"Chọn một thư mục",
"System locale":"Ngôn ngữ",
"System setting saved":"Đã lưu cài đặt hệ thống",
"VFS":"VFS"
,
"Add mount point":"Thêm điểm truy cập",
"Edit mount point":"Sửa điểm truy cập"
,
"Services":"Services",
"Startup":"Startup"
}

View File

@ -4,9 +4,9 @@
<afx-vbox>
<afx-file-view data-id = "fileview" view='tree' status = false></afx-file-view>
<input data-height = '26' type = "text" data-id = "filename" style="margin-left:5px; margin-right:5px;display:none;" />
<div data-height = '30' style=' text-align:right;padding-top:3px;'>
<afx-button data-id = "bt-ok" text = "Ok"></afx-button>
<afx-button data-id = "bt-cancel" text = "Cancel"></afx-button>
<div data-height = '30' style=' text-align:right;padding:3px;'>
<afx-button data-id = "bt-ok" text = "__(Ok)"></afx-button>
<afx-button data-id = "bt-cancel" text = "__(Cancel)"></afx-button>
</div>
</afx-vbox>
</afx-hbox>

View File

@ -2,18 +2,24 @@
_OS.setting.desktop = conf.desktop if conf.desktop
_OS.setting.applications = conf.applications if conf.applications
_OS.setting.appearance = conf.appearance if conf.appearance
_OS.setting.appearance.wp = {
url: "os://resources/themes/system/wp/wp2.jpg",
size: "cover",
repeat: "repeat"
} unless _OS.setting.appearance.wp
_OS.setting.appearance.wps = [] unless _OS.setting.appearance.wps
_OS.setting.user = conf.user
_OS.setting.VFS = conf.VFS if conf.VFS
_OS.setting.desktop.path = "home:///.desktop" unless _OS.setting.desktop.path
_OS.setting.desktop.path = "home://.desktop" unless _OS.setting.desktop.path
_OS.setting.desktop.menu = {} unless _OS.setting.desktop.menu
_OS.setting.VFS.mountpoints = [
#TODO: multi app try to write to this object, it neet to be cloned
{ text: "Applications", path: 'app:///', iconclass: "fa fa-adn", type: "app" },
{ text: "Home", path: 'home:///', iconclass: "fa fa-home", type: "fs" },
{ text: "Desktop", path: _OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" },
{ text: "OS", path: 'os:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Google Drive", path: 'gdv:///', iconclass: "fa fa-inbox", type: "fs" },
{ text: "Shared", path: 'shared:///' , iconclass: "fa fa-share-square", type: "fs" }
{ text: "__(Applications)", path: 'app://', iconclass: "fa fa-adn", type: "app" },
{ text: "__(Home)", path: 'home://', iconclass: "fa fa-home", type: "fs" },
{ text: "__(Desktop)", path: _OS.setting.desktop.path , iconclass: "fa fa-desktop", type: "fs" },
{ text: "__(OS)", path: 'os://', iconclass: "fa fa-inbox", type: "fs" },
{ text: "__(Google Drive)", path: 'gdv://', iconclass: "fa fa-inbox", type: "fs" },
{ text: "__(Shared)", path: 'shared://' , iconclass: "fa fa-share-square", type: "fs" }
] if not _OS.setting.VFS.mountpoints
_OS.setting.system = conf.system if conf.system
@ -28,9 +34,10 @@
} if not _OS.setting.system.startup
_OS.setting.system.pkgpaths = {
user: "home:///.packages",
system: "os:///packages"
user: "home://.packages",
system: "os://packages"
} unless _OS.setting.system.pkgpaths
_OS.setting.system.locale = "en_GB" unless _OS.setting.system.locale
_OS.setting.system.menu = {} unless _OS.setting.system.menu
_OS.setting.system.repositories = [] unless _OS.setting.system.repositories
_OS.setting.appearance.theme = "antos" unless _OS.setting.appearance.theme
@ -44,7 +51,7 @@
} unless _OS.setting.VFS.gdrive
#search for app
_API.onsearch "Applications", (t) ->
_API.onsearch "__(Applications)", (t) ->
ar = []
term = new RegExp t, "i"
for k, v of _OS.setting.system.packages when v.app

View File

@ -4,7 +4,7 @@
<li class = "afx-window-close" onclick = {close}></li>
<li if = {minimizable == true} class = "afx-window-minimize" onclick = {minimize}></li>
<li if = {resizable == true} class = "afx-window-maximize" onclick={maximize}></li>
<li ref = "dragger" class = "afx-window-title">{ apptitle }</li>
<li ref = "dragger" class = "afx-window-title">{ apptitle?apptitle.__():apptitle }</li>
</ul>
<div class = "afx-clear"></div>
<div ref = "content" class = "afx-window-content">
@ -49,6 +49,10 @@
{
return self[k]
}
self.root.update = function()
{
self.update()
}
minimize()
{
this.root.observable.trigger("hide")

View File

@ -1,9 +1,12 @@
<afx-calendar-view>
<div><i class ="prevmonth" onclick={prevmonth}></i>{text}<i onclick={nextmonth} class="nextmonth"></i></div>
<div><i class ="prevmonth" onclick={prevmonth}></i>
<afx-label text = {mtext}></afx-label>
<afx-label text = {year}></afx-label>
<i onclick={nextmonth} class="nextmonth"></i></div>
<afx-grid-view data-id ={"grid_" + rid} style = "height:100%;" ref = "grid" header = {header}> </afx-grid-view>
<script >
this.header = [{value:"Sun"},{value:"Mon"},{value:"Tue"},{value:"Wed"},{value:"Thu"},{value:"Fri"},{value:"Sat"}]
this.header = [{value:"__(Sun)"},{value:"__(Mon)"},{value:"__(Tue)"},{value:"__(Wed)"},{value:"__(Thu)"},{value:"__(Fri)"},{value:"__(Sat)"}]
this.root.observable = opts.observable
var self = this
this.day = 0
@ -17,7 +20,7 @@
return self[k]
}
this.on("mount", function (e) {
this.on("mount", function (e) {
self.refs.grid.root.observable = self.root.observable
calendar(null)
self.root.observable.on("gridcellselect", function(d){
@ -62,7 +65,7 @@
self.year = date.getFullYear()
var now ={ d:(new Date()).getDate(), m:(new Date()).getMonth(), y:(new Date()).getFullYear()}
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
months = ["__(January)", "__(February)", "__(March)", "__(April)", "__(May)", "__(June)", "__(July)", "__(August)", "__(September)", "__(October)", "__(November)", "__(December)"]
this_month = new Date(self.year, self.month, 1)
next_month = new Date(self.year, self.month + 1, 1)
@ -70,7 +73,7 @@
// Find out when this month starts and ends.
first_week_day = this_month.getDay()
days_in_this_month = Math.round((next_month.getTime() - this_month.getTime()) / (1000 * 60 * 60 * 24))
self.text = months[self.month] + ' ' + self.year
self.mtext = months[self.month]
var rows = []
var row = []
// Fill the first week of the month with the appropriate number of blanks.

View File

@ -1,3 +0,0 @@
<afx-dummy>
<yield/>
</afx-dummy>

View File

@ -0,0 +1,10 @@
<afx-dummy>
<yield/>
<script>
var self = this
self.root.update = function()
{
self.update()
}
</script>
</afx-dummy>

View File

@ -4,7 +4,7 @@
<div class = "treecontainer" ref="treecontainer">
<afx-tree-view ref = "treeview" observable = {root.observable}></afx-tree-view>
</div>
<div if = {status == true} class = "status" ref = "stbar"></div>
<afx-label if = {status == true} class = "status" ref = "stbar"></afx-label>
<script>
var self = this
self.root.observable = opts.observable || riot.observable()
@ -20,7 +20,7 @@
this.fetch = opts.fetch
this.chdir = opts.chdir
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.header = [{value:"File name"},{value: "Type", width:150}, {value: "Size", width:70}]
this.header = [{value:"__(File name)"},{value: "__(Type)", width:150}, {value: "__(Size)", width:70}]
self.root.set = function(k,v)
{
@ -49,7 +49,7 @@
var h = $(self.root).outerHeight()
var w = $(self.root).width()
if(self.refs.stbar)
h -= ($(self.refs.stbar).height() + 10)
h -= ($(self.refs.stbar.root).height() + 10)
$(self.refs.listview.root).css("height", h + "px")
$(self.refs.gridview.root).css("height", h + "px")
$(self.refs.treecontainer).css("height", h + "px")
@ -126,7 +126,8 @@
f(getTreeData(d))
})
})
$(self.refs.stbar).html("")
if(self.refs.stbar)
self.refs.stbar.root.set("text", "")
switch (self.view) {
case 'icon':
$(self.refs.listview.root).show()
@ -149,6 +150,7 @@
}
else
refreshData()
//console.log("update")
//calibre_size()
})
self.on("mount", function(){
@ -199,8 +201,8 @@
self.selectedFile = e.data
if(self.onfileselect)
self.onfileselect(e.data)
$(self.refs.stbar).empty()
$(self.refs.stbar).append($("<span>").append("Selected: " + e.data.filename + " (" + e.data.size + " bytes)"))//.html()
if(self.refs.stbar)
self.refs.stbar.root.set("text", __("Selected: {0} ({1} bytes)", e.data.filename, e.data.size?e.data.size:"0"))//.html()
})
self.root.observable.on("filedbclick", function(e){
if(e.id != self.rid ) return

View File

@ -6,6 +6,7 @@
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.on('mount', function(){
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
$(self.refs.container)
.css("display","flex")
.css("flex-direction","row")
@ -23,12 +24,26 @@
})
}
})
self.root.update = function()
{
self.update()
}
var calibrate_size = function()
{
var auto_width = []
var csize, ocwidth = 0, avaiheight;
avaiheight = $(self.root).height()
avaiWidth = $(self.root).width()
/*if(avaiheight == 0)
{
avaiheight = $(self.parent.root).height()
$(self.root).css("height", avaiheight+"px")
}
if(avaiWidth == 0)
{
avaiWidth = $(self.parent.root).width()
$(self.root).css("height", avaiWidth+"px")
}*/
$(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container)
.children()

View File

@ -0,0 +1,20 @@
<afx-html ref = "container">
<script>
this.content = opts.content
this.root.innerHTML = this.content
this.updateContent = undefined
var self = this
this.root.set = function(k, v)
{
self[k] = v
if(k == "content")
self.root.innerHTML = v
else if(k == "updateContent")
self.update()
}
this.on("update", function(){
if(self.updateContent)
self.root.innerHTML = self.updateContent()
})
</script>
</afx-html>

View File

@ -1,8 +1,8 @@
<afx-label>
<span style = {color?"color:" + color:""} >
<i if={iconclass} class = {iconclass} ></i>
<i if={icon} class="icon-style" style = { "background: url("+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{ text }
<i if={icon} class="icon-style" style = { "background: url("+window.OS.API.handler.get+"/"+icon+");background-size: 100% 100%;background-repeat: no-repeat;" }></i>
{ text?text.__():"" }
</span>
<script>
this.iconclass = opts.iconclass

View File

@ -1,16 +1,18 @@
<afx-list-view class = {dropdown: opts.dropdown == "true"}>
<div class = "list-container" ref = "container">
<div if = {opts.dropdown == "true"} ref = "current" style = {opts.width?"min-width:" + opts.width + "px;":"min-width:150px;"} onclick = {show_list}>
<afx-list-view class = {dropdown: opts.dropdown == "true"} style = "display:flex; flex-direction:column">
<div class = "list-container" ref = "container" style="flex:1;">
<div if = {opts.dropdown == "true"} ref = "current" style = {opts.width?"min-width:" + opts.width + "px;":""} onclick = {show_list}></div>
<ul ref = "mlist" >
<li each={item,i in items } class={selected: parent._autoselect(item,i)} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select}>
<afx-label class = {item.class} color = {item.color} iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label>
<i if = {item.closable} class = "closable" click = {parent._remove}></i>
<ul if = {item.complex} class = "complex-content">
<li each = {ctn,j in item.detail} class = {ctn.class}>{ctn.text.toString()}</li>
</ul>
</li>
</ul>
</div>
<ul ref = "mlist">
<li each={item,i in items } class={selected: parent._autoselect(item,i)} ondblclick = {parent._dbclick} onclick = {parent._select} oncontextmenu = {parent._select}>
<afx-label class = {item.class} color = {item.color} iconclass = {item.iconclass} icon = {item.icon} text = {item.text}></afx-label>
<i if = {item.closable} class = "closable" click = {parent._remove}></i>
<ul if = {item.complex} class = "complex-content">
<li each = {ctn,j in item.detail} class = {ctn.class}>{ctn.text}</li>
</ul>
</li>
</ul>
<div if = {opts.dropdown != "true" && buttons} class = "button_container">
<afx-button each = {btn,i in buttons} text = {btn.text} icon = {btn.icon} iconclass = {btn.iconclass} onbtclick = {btn.onbtclick}></afx-button>
</div>
<script>
this.items = opts.items || []
@ -19,6 +21,7 @@
self.onlistselect = opts.onlistselect
self.onlistdbclick = opts.onlistdbclick
self.onitemclose = opts.onitemclose
self.buttons = opts.buttons
var onclose = false
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
self.root.set = function(k,v)
@ -112,8 +115,14 @@
}
this.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
if(opts.dropdown == "true")
{
self.root.observable.on("calibrate", function(){
$(self.refs.container).css("width", $(self.root).width() + "px" )
$(self.refs.mlist).css("width", $(self.root).width() + "px" )
})
$(document).click(function(event) {
if(!$(event.target).closest(self.refs.container).length) {
$(self.refs.mlist).hide()
@ -171,7 +180,7 @@
if(opts.dropdown == "true")
{
$(self.refs.mlist).hide()
$(self.refs.current).html(it.text)
$(self.refs.current).html(it.text.__())
}
if(self.onlistselect)

View File

@ -8,12 +8,16 @@
<span if={data.shortcut} class = "shortcut">{data.shortcut}</span>
</a>
<afx-menu if={data.child != null && data.child.length > 0} child={data.child} onmenuselect = {data.onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
<afx-menu ref = "submenus" index = {i} if={data.child != null && data.child.length > 0} child={data.child} onmenuselect = {data.onmenuselect} observable = {parent.root.observable} rootid = {parent.rid}></afx-menu>
</li>
<li class="afx-corner-fix"></li>
</ul>
<script>
this.items = opts.child || []
if(opts.index != undefined)
this.index = opts.index
else
this.index = -1
var isRoot
var lastChecked = undefined
if(opts.rootid)
@ -48,6 +52,7 @@
self[k] = v
self.update()
}
self.root.push = function(e,u)
{
self.items.push(e)

View File

@ -6,7 +6,7 @@
else
this.swon = false
var self = this
this.root.observable = opts.observable
//this.root.observable = opts.observable
if(opts.enable != undefined)
this.enable = opts.enable
else
@ -31,9 +31,11 @@
opts.swon = !self.swon
self.update()
}
/*this.on("mount", function(){
})*/
this.on("update", function(e){
self.swon = opts.swon
self.onchange = opts.onchange
self.swon = typeof opts.swon == "function"?opts.swon():opts.swon
})
toggle(e)
{

View File

@ -39,6 +39,10 @@
{
return self[k]
}
self.root.update = function()
{
self.update()
}
this.on('mount', function() {
//console.log(self.refs.aOsmenu.root)
$(self.refs.aOsmenu.root).css("z-index",1000000)

View File

@ -1,9 +1,8 @@
<afx-tab-container>
<afx-tab-bar>
<afx-list-view ref = "list" />
<script>
var self = this
this.closable = opts.closable || false
self.root.observable = opts.observable || riot.observable()
self.ontabselect = opts.ontabselect
get_observable(){
return self.root.observable
@ -17,6 +16,7 @@
self.update(true)
}
self.on("mount", function(){
self.root.observable = opts.observable || (self.parent && self.parent.root && self.parent.root.observable) || riot.observable()
self.refs.list.root.observable = self.root.observable
/*self.root.observable.on("listselect", function(){
console.log("list select")
@ -71,4 +71,4 @@
}
</script>
</afx-tab-container>
</afx-tab-bar>

View File

@ -0,0 +1,91 @@
<afx-tab-container>
<afx-hbox ref = "mybox" if = {bar == "left"}>
<afx-tab-bar data-ref="tabbar" ></afx-tab-bar>
<div data-ref="container"></div>
</afx-hbox>
<afx-vbox ref = "mybox" if = { bar == "top"}>
<afx-tab-bar data-ref="tabbar" ></afx-tab-bar>
<div data-ref="container"></div>
</afx-vbox>
<script>
this.bar = opts.bar || "top"
this.barwidth = opts.barwidth
this.barheight = opts.barheight
var schemes = []
var self = this
var calibrate = function()
{
$(self.refs.mybox.root).css("width", $(self.root).width()+"px")
$(self.refs.mybox.root).css("height", $(self.root).height()+"px")
self.root.observable.trigger("calibrate")
}
self.on("mount", function () {
self.tabbar = $("[data-ref='tabbar']", self.root)[0]
self.container = $("[data-ref='container']", self.root)[0]
if(self.barwidth)
$(self.tabbar).attr("data-width", self.barwidth)
if(self.barheight)
$(self.tabbar).attr("data-height", self.barheight)
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
self.tabbar.set("ontabselect", function(e){
$(self.container).children().each(function(el){
$(this).hide()
})
$(e.data.scheme).show()
e.data.handler.render()
calibrate()
})
self.root.observable.on("resize", function(){
calibrate()
})
})
self.on("update", function(){
$(self.container).children().each(function(e){
if(this.update) this.update()
})
})
var render = function(el)
{
var sch = $.parseHTML(el.scheme)
$(self.container).append(sch)
el.scheme = sch
riot.mount(sch, {observable: self.root.observable})
$(sch).hide()
el.handler = el.handler(sch[0])
//console.log(el.handler)
//el.handler.render()
self.root.observable.trigger("tabrendered")
//self.root.observable.trigger("calibrate")
}
var addTab = function(el)
{
if(!el.f)
el.f = (function(){})
self.tabbar.push(el)
if(el.url)
{
el.url.asFileHandler().read(function(d){
el.scheme = d
render(el)
})
}
else
{
render(el)
}
}
self.root.setTabs = function(arr)
{
if(arr.length <= 0)
{
self.tabbar.set("selected", 0)
return
}
self.root.observable.one("tabrendered", function(){
arr.splice(0,1)
self.root.setTabs(arr)
})
addTab(arr[0])
}
</script>
</afx-tab-container>

View File

@ -1,5 +1,4 @@
<afx-tree-view>
<div class={afx_tree_item_selected:treeroot.selectedItem && treeroot.selectedItem.treepath == data.treepath, afx_folder_item: isFolder(), afx_tree_item_odd: index%2 != 0 } onclick={select} ondblclick = {_dbclick} oncontextmenu = {select}>
<ul style = "padding:0;margin:0;white-space: nowrap;">
<li ref = "padding" ></li>
@ -12,8 +11,6 @@
</li>
</ul>
</div>
<ul if={ isFolder() } show={ isFolder() && open }>
<li each={ child, i in data.nodes }>
<afx-tree-view ontreeselect = {parent.ontreeselect} index = {i} fetch = {parent.fetch} ontreedbclick = {parent.ontreedbclick} data={child} indent={indent+1} observable = {parent.root.observable} path = {parent.data.treepath + ">" + i} treeroot= {parent.treeroot}></afx-tree-view>

View File

@ -6,6 +6,7 @@
var self = this
this.rid = $(self.root).attr("data-id") || Math.floor(Math.random() * 100000) + 1
this.on('mount', function(){
self.root.observable = (self.parent && self.parent.root && self.parent.root.observable) || opts.observable || riot.observable()
$(self.refs.container)
.css("display","flex")
.css("flex-direction","column")
@ -25,13 +26,26 @@
})
}
})
self.root.update = function()
{
self.update()
}
var calibrate_size = function()
{
var auto_height = []
var csize, ocheight = 0, avaiheight;
avaiheight = $(self.root).height()
avaiwidth = $(self.root).width()
/*if(avaiheight == 0)
{
avaiheight = $(self.parent.root).height()
$(self.root).css("height", avaiheight+"px")
}
if(avaiwidth == 0)
{
avaiwidth = $(self.parent.root).width()
$(self.root).css("height", avaiwidth+"px")
}*/
$(self.refs.container).css("height",avaiheight + "px")
$(self.refs.container)
.children()

View File

@ -1,8 +1,8 @@
String.prototype.asFileHandler = () ->
list = @split ":///"
list = @split "://"
handlers = _API.VFS.findHandlers list[0]
if not handlers or handlers.length is 0
_courrier.osfail "VFS unknown handler: #{@}", (_API.throwe "OS.VFS"), @
_courrier.osfail __("VFS unknown handler: {0}", @), (_API.throwe "OS.VFS"), @
return null
return new handlers[0](@)
@ -25,7 +25,7 @@ class BaseFileHandler
@ready = false
return unless p
@path = p.toString()
list = @path.split ":///"
list = @path.split "://"
@protocol = list[0]
return unless list.length > 1
re = list[1].replace(/^\/+|\/+$/g, '')
@ -33,7 +33,8 @@ class BaseFileHandler
@genealogy = re.split("/")
@basename = @genealogy[@genealogy.length - 1] unless @isRoot()
@ext = @basename.split( "." ).pop() unless @basename.lastIndexOf(".") is 0 or @basename.indexOf( "." ) is -1
asFileHandler: () ->
@
isRoot: () -> (not @genealogy) or (@genealogy.size is 0)
child: (name) ->
@ -63,10 +64,10 @@ class BaseFileHandler
reader.onload = () ->
f reader.result
reader.onerror = (e) ->
return _courrier.osfail "Cannot ecode file: #{me.path}", (_API.throwe "OS.VFS"), e
return _courrier.osfail __("VFS Cannot encode file: {0}", me.path), (_API.throwe "OS.VFS"), e
parent: () ->
return @ if @isRoot()
return (@protocol + ":///" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
return (@protocol + "://" + (@genealogy.slice 0 , @genealogy.length - 1).join "/")
onready: (f, err) ->
# read meta data
@ -132,7 +133,7 @@ class BaseFileHandler
# for main action read, write, remove, execute
# must be implemented by subclasses
action: (n, p, f) ->
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
# now export the class
self.OS.API.VFS.BaseFileHandler = BaseFileHandler
@ -154,7 +155,7 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
return _API.handler.fileblob @path, f if p is "binary"
_API.handler.readfile @path, f, if p then p else "text"
when "mk"
return f { error: "#{@path} is not a directory" } if @info.type is "file"
return f { error: __("{0} is not a directory", @path) } if @info.type is "file"
_API.handler.mkdir "#{@path}/#{p}", f
when "write"
@sendB64 p, (data) ->
@ -174,7 +175,7 @@ class RemoteFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
_API.handler.move @path, p, f
else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^(home|desktop|os|Untitled)$", RemoteFileHandler
@ -217,7 +218,7 @@ class ApplicationHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^app$", ApplicationHandler
@ -267,7 +268,7 @@ class BufferFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^mem$", BufferFileHandler
@ -309,6 +310,6 @@ class SharedFileHandler extends self.OS.API.VFS.BaseFileHandler
when "move"
return
else
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^shared$", SharedFileHandler

View File

@ -1,13 +1,13 @@
# GoogleDrive File Handler
G_CACHE = {"gdv:///":{ id: "root", mime: 'dir' } }
G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } }
class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
constructor: (path) ->
super path
me = @
@setting = _OS.setting.VFS.gdrive
return _courrier.oserror "Unknown API setting for google drive VFS", (_API.throwe "OS.VFS"), null unless @setting
return _courrier.oserror __("Unknown API setting for {0}", "GAPI"), (_API.throwe "OS.VFS"), null unless @setting
@gid = 'root' if @isRoot()
@cache = ""
@ -17,7 +17,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
fn = (r) ->
return f() if r
# perform the login
G_CACHE = {"gdv:///":{ id: "root", mime: 'dir' } }
G_CACHE = {"gdv://":{ id: "root", mime: 'dir' } }
gapi.auth2.getAuthInstance().signIn()
if _API.libready @setting.apilink
@ -41,12 +41,13 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
gapi.auth2.getAuthInstance().isSignedIn.listen (r) ->
fn(r)
_GUI.openDialog "YesNoDialog", (d) ->
return _courrier.osinfo "User abort the authentification" unless d
return _courrier.osinfo __("User abort the authentication") unless d
fn(gapi.auth2.getAuthInstance().isSignedIn.get())
, "Authentification", { text: "Would you like to login to Google Drive ?" }
, __("Authentication")
, { text: __("Would you like to login to {0}?", "Google Drive") }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot init GAPI: #{err.error}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot init {0}: {1}", "GAPI",err.error), (_API.throwe "OS.VFS"), err
meta: (f) ->
me = @
@ -67,7 +68,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f(r)
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot get meta #{me.gid}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot get meta data for {0}", me.gid), (_API.throwe "OS.VFS"), err
else
#console.log "Find file in ", me.parent()
fp = me.parent().asFileHandler()
@ -89,7 +90,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files[0] }
.catch (err) ->
_API.loaded q1, "FAIL"
_courrier.oserror "VFS cannot get meta #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot get meta data for {0}", me.path), (_API.throwe "OS.VFS"), err
fields: () ->
return "webContentLink, id, name,mimeType,description, kind, parents, properties, iconLink, createdTime, modifiedTime, owners, permissions, fullFileExtension, fileExtension, size"
@ -111,7 +112,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
_API.loading q, "GAPI"
error = (e, s) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot save : #{me.path}", e, s
_courrier.oserror __("VFS cannot save : {0}", me.path), e, s
xhr.onreadystatechange = () ->
if ( xhr.readyState == 4 )
if ( xhr.status == 200 )
@ -154,7 +155,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
f { result: r.result.files }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot read #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
else
gapi.client.drive.files.get {
fileId: me.info.id,
@ -163,13 +164,13 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
_API.loaded q, "OK"
return f r.body unless p is "binary"
f r.body.asUnit8Array()
f r.body.asUint8Array()
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot get read #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot read : {0}", me.path), (_API.throwe "OS.VFS"), err
when "mk"
return f { error: "#{@path} is not a directory" } unless @isFolder()
return f { error: __("{0} is not a directory", @path) } unless @isFolder()
meta =
name: p,
parents: [@info.id],
@ -182,12 +183,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
_API.loaded q, "OK"
#console.log r
return _courrier.oserror "VFS cannot create : #{p}", (_API.throwe "OS.VFS"), r unless r and r.result
return _courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.child p] = { id: r.result.id, mime: "dir" }
f r
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot create #{p}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot create : {0}", p), (_API.throwe "OS.VFS"), err
return
@ -211,12 +212,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror "VFS cannot write : #{me.path}", (_API.throwe "OS.VFS"), r unless r and r.result
return _courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), r unless r and r.result
G_CACHE[me.path] = { id: r.result.id, mime: p }
me.save r.result.id, p, f
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot write #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot write : {0}", me.path), (_API.throwe "OS.VFS"), err
when "upload"
return unless @isFolder()
@ -244,12 +245,12 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
.then (r) ->
#console.log r
_API.loaded q, "OK"
return _courrier.oserror "VFS cannot delete : #{me.path}", (_API.throwe "OS.VFS"), r unless r
return _courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
G_CACHE[me.path] = null
f { result: true }
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot delete #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot delete : {0}", me.path), (_API.throwe "OS.VFS"), err
when "publish"
_API.loaded q, "OK"
@ -262,7 +263,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror "VFS cannot get file : #{me.path}", (_API.throwe "OS.VFS"), r unless r.body
return _courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), r unless r.body
bytes = []
for i in [0..(r.body.length - 1)]
bytes.push r.body.charCodeAt i
@ -271,7 +272,7 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
_API.saveblob me.basename, blob
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot fetch #{me.path}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot download file : {0}", me.path), (_API.throwe "OS.VFS"), err
when "move"
dest = p.asFileHandler().parent().asFileHandler()
@ -285,16 +286,16 @@ class GoogleDriveHandler extends this.OS.API.VFS.BaseFileHandler
}
.then (r) ->
_API.loaded q, "OK"
return _courrier.oserror "VFS cannot move : #{me.path}", (_API.throwe "OS.VFS"), r unless r
return _courrier.oserror __("VFS cannot move : {0}", me.path), (_API.throwe "OS.VFS"), r unless r
f r
.catch (err) ->
_API.loaded q, "FAIL"
_courrier.oserror "VFS cannot move #{me.gid}", (_API.throwe "OS.VFS"), err
_courrier.oserror __("VFS cannot move : {0}", me.gid), (_API.throwe "OS.VFS"), err
, (err) ->
_API.loaded q, "FAIL"
else
_API.loaded q, "FAIL"
return _courrier.osfail "VFS unknown action: #{n}", (_API.throwe "OS.VFS"), n
return _courrier.osfail __("VFS unknown action: {0}", n), (_API.throwe "OS.VFS"), n
self.OS.API.VFS.register "^gdv$", GoogleDriveHandler
@ -315,7 +316,7 @@ self.OS.API.onsearch "Google Drive", (t) ->
return arr
self.OS.onexit "cleanUpGoogleDrive", () ->
G_CACHE = { "gdv:///": { id: "root", mime: 'dir' } }
G_CACHE = { "gdv://": { id: "root", mime: 'dir' } }
return unless _OS.setting.VFS.gdrive and _API.libready _OS.setting.VFS.gdrive.apilink
auth2 = gapi.auth2.getAuthInstance()
return unless auth2

View File

@ -4,6 +4,7 @@
<title>AntOS webOS</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="resources/themes/system/font-awesome.css" rel="stylesheet">
<link id="ostheme" rel="stylesheet" href="">
<!--link href="theme/antos/style.css" rel="stylesheet"-->
<script src="scripts/jquery-3.2.1.min.js"></script>

View File

@ -14,7 +14,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
app = _PM.appByPid item[0].value
app.quit() if app
header = [{width:50,value:"Pid"},{value:"Name"}, {value:"Type", width:80},{width:75,value:"Alive (ms)"}]
header = [{width:50,value: "__(Pid)"},{value:"__(Name)"}, {value:"__(Type)", width:80},{width:75,value: "__(Alive (ms))"}]
@gdata =
processes:{}
alive:[]
@ -36,7 +36,7 @@ class ActivityMonitor extends this.OS.GUI.BaseApplication
{icon:if _APP[a.name].type == 1 then _APP[a.name].meta.icon else a.icon,
iconclass:if _APP[a.name].type == 1 then _APP[a.name].meta.iconclass else a.iconclass,
value:a.name},
{value: if _APP[a.name].type == 1 then "Application" else "Service"}
{value: if _APP[a.name].type == 1 then "__(Application)" else "__(Service)"}
{value: now - a.birth}
]
me.gdata.alive.push a.pid

View File

@ -1,6 +1,6 @@
<afx-app-window data-id = "am-window" apptitle="" width="400" height="300">
<afx-vbox>
<afx-grid-view data-id = "mygrid"></afx-grid-view>
<afx-button data-height="30" data-id = "btkill" text = "Kill process" iconclass="fa fa-times"></afx-button>
<afx-button data-height="30" data-id = "btkill" text = "__(Kill process)" iconclass="fa fa-times"></afx-button>
</afx-vbox>
</afx-app-window>

View File

@ -2,30 +2,30 @@
<afx-vbox >
<div data-height="5"></div>
<afx-hbox data-height = "30" >
<afx-label data-width= "70" text = "Title:"></afx-label>
<afx-label data-width= "70" text = "__(Title)"></afx-label>
<input type = "text" name="title" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30" >
<afx-label text = "Subtitle:" data-width= "70"></afx-label>
<afx-label text = "__(Subtitle)" data-width= "70"></afx-label>
<input type = "text" name="subtitle" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30" >
<afx-label text = "Location:" data-width= "70"></afx-label>
<afx-label text = "__(Location)" data-width= "70"></afx-label>
<input type = "text" name="location" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30" >
<afx-label text = "From:" data-width= "70"></afx-label>
<afx-label text = "__(From)" data-width= "70"></afx-label>
<input type = "text" name="start" input-class = "user-input"/>
<afx-label text = "To:" style="text-align:center;" data-width= "70"></afx-label>
<input type = "text" name="end" input-class = "user-input"/>
</afx-hbox>
<afx-label data-height = "30" text = "Content:" style = "margin-left:5px;"/>
<afx-label data-height = "30" text = "Content" style = "margin-left:5px;"/>
<div data-id="editor-container">
<textarea name="content" data-id = "contentarea" />
</div>
<afx-hbox data-height = "35">
<div></div>
<afx-button iconclass = "fa fa-save" data-id = "bt-cv-sec-save" data-width="60" text = "Save"/>
<afx-button iconclass = "fa fa-save" data-id = "bt-cv-sec-save" data-width="60" text = "__(Save)"/>
</afx-hbox>
</afx-vbox>
</afx-app-window>

View File

@ -2,9 +2,9 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
constructor: () ->
super "BloggerCategoryDialog", {
tags: [
{ tag: "afx-label", att: "data-height = '20', text = 'Pick a parent:'" },
{ tag: "afx-label", att: "data-height = '20', text = 'Pick a parent'" },
{ tag: "afx-tree-view" },
{ tag: "afx-label", att: "data-height = '20', text = 'Category name:'" },
{ tag: "afx-label", att: "data-height = '20', text = 'Category name'" },
{ tag: "input", att: "type = 'text' data-height = '20'" }
],
width: 200,
@ -15,10 +15,10 @@ class BloggerCategoryDialog extends this.OS.GUI.BasicDialog
label: "0k",
onclick: (d) ->
sel = (d.find "content1").get "selectedItem"
return d.notify "Please select a parent category" unless sel
return d.notify __("Please select a parent category") unless sel
val = (d.find "content3").value
return d.notify "Please enter category name" if val is "" and not d.data.selonly
return d.notify "Parent can not be the category itself" if d.data.cat and d.data.cat.id is sel.id
return d.notify __("Please enter category name") if val is "" and not d.data.selonly
return d.notify __("Parent can not be the category itself") if d.data.cat and d.data.cat.id is sel.id
d.handler { p: sel, value: val } if d.handler
d.quit()
},
@ -66,7 +66,7 @@ class BloggerCVSectionDiaglog extends this.OS.GUI.BaseDialog
($ (@select '[class="CodeMirror cm-s-paper CodeMirror-wrap"]')[0]).css "min-height", "50px"
@on "vboxchange", () ->
me.resizeContent()
console.log "resize content"
inputs = me.select "[input-class='user-input']"
(($ v).val me.data[v.name] for v in inputs ) if me.data
@editor.value me.data.content if me.data and me.data.content
@ -75,7 +75,7 @@ class BloggerCVSectionDiaglog extends this.OS.GUI.BaseDialog
console.log inputs
data[v.name] = ($ v).val() for v in inputs
data.content = me.editor.value()
return me.notify "Title or content must not be blank" if data.title is "" and data.content is ""
return me.notify __("Title or content must not be blank") if data.title is "" and data.content is ""
#return me.notify "Content must not be blank" if data.content is ""
data.id = me.data.id if me.data and me.data.id
me.handler data if me.handler

View File

@ -42,11 +42,11 @@ class Blogger extends this.OS.GUI.BaseApplication
pid: d.p.id,
publish: 1
me.cvcatdb.save c, (r) ->
me.error "Cannot add new category" if r.error
me.error __("Cannot add new category") if r.error
me.refreshCVCat()
#update the list
, "Add category", { tree: me.cvlist.get "data" }
, __("Add category"), { tree: me.cvlist.get "data" }
(@find "cv-cat-edit").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem"
@ -59,9 +59,9 @@ class Blogger extends this.OS.GUI.BaseApplication
name: d.value
me.cvcatdb.save c, (r) ->
return me.error "Cannot Edit category" if r.error
me.refreshCVCat()
, "Edit category", { tree: (me.cvlist.get "data"), cat: cat }
return me.error __("Cannot Edit category") if r.error
me.refreshCVCat()
, __("Edit category"), { tree: (me.cvlist.get "data"), cat: cat }
(@find "cv-cat-del").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem"
@ -70,26 +70,26 @@ class Blogger extends this.OS.GUI.BaseApplication
(d) ->
return unless d
me.deleteCVCat cat
, "Delete cagegory" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{cat.name} ?" }
, __("Delete category") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", cat.name) }
(@find "cv-sec-add").set "onbtclick", (e) ->
cat = me.cvlist.get "selectedItem"
return me.notify "Please select a category" unless cat and cat.id isnt 0
return me.notify __("Please select a category") unless cat and cat.id isnt 0
me.openDialog "BloggerCVSectionDiaglog", (d) ->
d.cid = Number cat.id
d.start = Number d.start
d.end = Number d.end
d.publish = 1
me.cvsecdb.save d, (r) ->
return me.error "Cannot save section: #{r.error}" if r.error
return me.error __("Cannot save section: {0}", r.error) if r.error
me.CVSectionByCID Number(cat.id)
, "New section entry for #{cat.name}", null
, __("New section entry for {0}", cat.name), null
(@find "cv-sec-move").set "onbtclick", (e) ->
sec = (me.find "cv-sec-list").get "selected"
return me.notify "Please select a section to move" unless sec
return me.notify __("Please select a section to move") unless sec
me.openDialog "BloggerCategoryDialog", (d) ->
c =
@ -97,14 +97,14 @@ class Blogger extends this.OS.GUI.BaseApplication
cid: d.p.id
me.cvsecdb.save c, (r) ->
return me.error "Cannot move section" if r.error
return me.error __("Cannot move section") if r.error
me.CVSectionByCID(sec.cid)
(me.find "cv-sec-list").set "selected", -1
, "Move to", { tree: (me.cvlist.get "data"), selonly: true }
, __("Move to"), { tree: (me.cvlist.get "data"), selonly: true }
(@find "cv-sec-edit").set "onbtclick", (e) ->
sec = (me.find "cv-sec-list").get "selected"
return me.notify "Please select a section to edit" unless sec
return me.notify __("Please select a section to edit") unless sec
me.openDialog "BloggerCVSectionDiaglog", (d) ->
d.cid = Number sec.cid
@ -112,10 +112,10 @@ class Blogger extends this.OS.GUI.BaseApplication
d.end = Number d.end
d.publish = Number sec.publish
me.cvsecdb.save d, (r) ->
return me.error "Cannot save section: #{r.error}" if r.error
return me.error __("Cannot save section: {0}", r.error) if r.error
me.CVSectionByCID Number(sec.cid)
, "Modify section entry", sec
, __("Modify section entry"), sec
@editor = new SimpleMDE
element: me.find "markarea"
@ -124,14 +124,14 @@ class Blogger extends this.OS.GUI.BaseApplication
indentWithTabs: true
toolbar: [
{
name: "new",
name: __("New"),
className: "fa fa-file",
action: (e) ->
me.bloglist.set "selected", -1
me.clearEditor()
},
{
name: "save",
name: __("Save"),
className: "fa fa-save",
action: (e) ->
me.saveBlog()
@ -145,14 +145,21 @@ class Blogger extends this.OS.GUI.BaseApplication
action: (e) ->
me.openDialog "FileDiaLog", (d, n, p) ->
p.asFileHandler().publish (r) ->
return me.error "Cannot export file for embeding to text" if r.error
return me.error __("Cannot export file for embedding to text") if r.error
doc = me.editor.codemirror.getDoc()
doc.replaceSelection "![](#{me._api.handler.shared}/#{r.result})"
, "Select image file", { mimes: ["image/.*"] }
, __("Select image file"), { mimes: ["image/.*"] }
},
{
name:"Youtube",
className: "fa fa-youtube",
action: (e) ->
doc = me.editor.codemirror.getDoc()
doc.replaceSelection "[[youtube:]]"
}
"|",
{
name: "preview",
name: __("Preview"),
className: "fa fa-eye no-disable",
action: (e) ->
me.previewOn = !me.previewOn
@ -162,22 +169,27 @@ class Blogger extends this.OS.GUI.BaseApplication
@bloglist.set "onlistselect", (e) ->
sel = me.bloglist.get "selected"
return unless sel
me.editor.value atob(sel.content)
me.inputtags.value = sel.tags
(me.find "blog-publish").set "swon", (if Number(sel.publish) then true else false)
me.blogdb.get Number(sel.id), (r) ->
me.error __("Cannot fetch the entry content") if r.error
me.editor.value atob(r.result.content)
me.inputtags.value = r.result.tags
(me.find "blog-publish").set "swon", (if Number(r.result.publish) then true else false)
@.bloglist.set "onitemclose", (e) ->
me.openDialog "YesNoDialog", (b) ->
return unless b
me.blogdb.delete e.item.item.id, (r) ->
return me.error "Cannot delete: #{r.error}" if r.error
return me.error __("Cannot delete: {0}", r.error) if r.error
me.bloglist.remove e.item.item, true
me.bloglist.set "selected", -1
me.clearEditor()
, "Delete a post" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete this post ?" }
, __("Delete a post") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete this post ?") }
return false
@bindKey "CTRL-S", () ->
sel = me.tabbar.get "selidx"
return unless sel is 2
me.saveBlog()
@on "vboxchange", () ->
me.resizeContent()
# USER TAB
@ -187,7 +199,7 @@ class Blogger extends this.OS.GUI.BaseApplication
when 0 #user info
@userdb.get null, (d) ->
return me.error "Cannot fetch user data" if d.error
return me.error __("Cannot fetch user data") if d.error
me.user = d.result[0]
inputs = me.select "[input-class='user-input']"
($ v).val me.user[v.name] for v in inputs
@ -200,11 +212,11 @@ class Blogger extends this.OS.GUI.BaseApplication
me = @
inputs = @select "[input-class='user-input']"
@user[v.name] = ($ v).val() for v in inputs
return @notify "Full name must be entered" if not @user.fullname or @user.fullname is ""
return @notify __("Full name must be entered") if not @user.fullname or @user.fullname is ""
#console.log @user
@userdb.save @user, (r) ->
return me.error "Cannot save user data" if r.error
return me.notify "User data updated"
return me.error __("Cannot save user data") if r.error
return me.notify __("User data updated")
# PORFOLIO TAB
@ -220,7 +232,7 @@ class Blogger extends this.OS.GUI.BaseApplication
@cvcatdb.find cnd, (d) ->
if d.error
me.cvlist.set "data", data
return me.notify "Cannot fetch CV categories"
return me.notify __("Cannot fetch CV categories")
me.fetchCVCat d.result, data, "0"
me.cvlist.set "data", data
#it = (me.cvlist.find "pid", "2")[0]
@ -246,10 +258,10 @@ class Blogger extends this.OS.GUI.BaseApplication
cond = ({ "=": { cid: v } } for v in ids)
# delete all content
@cvsecdb.delete { "or": cond }, (r) ->
return me.error "Cannot delete all content of: #{cat.name} [#{r.error}]" if r.error
return me.error __("Cannot delete all content of: {0} [{1}]", cat.name, r.error) if r.error
cond = ({ "=": { id: v } } for v in ids)
me.cvcatdb.delete { "or": cond }, (re) ->
return me.error "Cannot delete the category: #{cat.name} [#{re.error}]" if re.error
return me.error __("Cannot delete the category: {0} [{1}]", cat.name, re.error) if re.error
me.refreshCVCat()
CVSectionByCID: (cid) ->
@ -261,10 +273,10 @@ class Blogger extends this.OS.GUI.BaseApplication
order:
start: "DESC"
@cvsecdb.find cond, (d) ->
return me.notify "Section list is empty, please add one" if d.error
return me.notify __("Section list is empty, please add one") if d.error
v.text = v.title for v in d.result
items = []
$(me.find "cv-sec-status").html "Found #{d.result.length} sections"
$(me.find "cv-sec-status").html __("Found {0} sections", d.result.length)
for v in d.result
v.text = v.title
v.complex = true
@ -286,10 +298,10 @@ class Blogger extends this.OS.GUI.BaseApplication
me.openDialog "YesNoDialog", (b) ->
return unless b
me.cvsecdb.delete e.item.item.id, (r) ->
return me.error "Cannot delete the section: #{r.error}" if r.error
return me.error __("Cannot delete the section: {0}", r.error) if r.error
el.remove e.item.item, true
, "Delete section" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{e.item.item.text} ?" }
, __("Delete section") ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?",e.item.item.text) }
return false
el.set "items", items
@ -300,8 +312,8 @@ class Blogger extends this.OS.GUI.BaseApplication
tags = @inputtags.value
content = @editor.value()
title = (new RegExp "^#+(.*)\n", "g").exec content
return @notify "Please insert a title in the text: beginning with heading" unless title and title.length is 2
return @notify "Please enter tags" if tags is ""
return @notify __("Please insert a title in the text: beginning with heading") unless title and title.length is 2
return @notify __("Please enter tags") if tags is ""
d = new Date()
data =
content: content.asBase64()
@ -311,14 +323,40 @@ class Blogger extends this.OS.GUI.BaseApplication
ctimestr: if sel then sel.ctimestr else d.toString()
utime: d.timestamp()
utimestr: d.toString()
rendered: me.editor.options.previewRender(content).asBase64()
rendered: me.process(me.editor.options.previewRender(content))
publish: if ((@find "blog-publish").get "swon") then 1 else 0
data.id = sel.id if sel
#save the data
@blogdb.save data, (r) ->
return me.error "Cannot save blog: #{r.error}" if r.error
return me.error __("Cannot save blog: {0}", r.error) if r.error
me.loadBlogs()
process: (text) ->
# find video tag and rendered it
embed = (id) ->
return """
<iframe
class = "embeded-video"
width="560" height="315"
src="https://www.youtube.com/embed/#{id}"
frameborder="0" allow="encrypted-media" allowfullscreen
></iframe>
"""
re = /\[\[([^:]*):([^\]]*)\]\]/g
replace = []
while (found = re.exec text) isnt null
replace.push found
return text.asBase64() unless replace.length > 0
ret = ""
begin = 0
for it in replace
ret += text.substring begin, it.index
ret += embed(it[2])
begin = it.index + it[0].length
ret += text.substring begin, text.length
#console.log ret
return ret.asBase64()
clearEditor:() ->
@.editor.value ""
@.inputtags.value = ""
@ -330,16 +368,23 @@ class Blogger extends this.OS.GUI.BaseApplication
cond =
order:
ctime: "DESC"
fields: [
"id",
"title",
"ctimestr",
"ctime",
"utime",
"utimestr"
]
@blogdb.find cond, (r) ->
return me.notify "No post found: #{r.error}" if r.error
return me.notify __("No post found: {0}", r.error) if r.error
for v in r.result
v.text = v.title
v.complex = true
v.closable = true
v.content = v.content.unescape()
v.detail = [
{ text: "Created: #{v.ctimestr}", class: "blog-dates" },
{ text: "Updated: #{v.utimestr}", class: "blog-dates" }]
{ text: __("Created: {0}", v.ctimestr), class: "blog-dates" },
{ text: __("Updated: {0}", v.utimestr), class: "blog-dates" }]
me.bloglist.set "items", r.result
if selidx isnt -1
me.bloglist.set "selected", selidx

View File

@ -5,36 +5,36 @@
<afx-hbox data-id="user-container" data-height="100%">
<afx-vbox>
<afx-hbox data-height = "30">
<afx-label data-width= "70" text = "Full name:"></afx-label>
<afx-label data-width= "70" text = "__(Full name)"></afx-label>
<input type = "text" name="fullname" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30">
<afx-label text = "Address:" data-width= "70"></afx-label>
<afx-label text = "__(Address)" data-width= "70"></afx-label>
<input type = "text" name="address" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30">
<afx-label text = "Phone:" data-width= "70"></afx-label>
<afx-label text = "__(Phone)" data-width= "70"></afx-label>
<input type = "text" name="Phone" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30">
<afx-label text = "Email:" data-width= "70"></afx-label>
<afx-label text = "__(Email)" data-width= "70"></afx-label>
<input type = "text" name="email" input-class = "user-input"/>
</afx-hbox>
<afx-hbox data-height = "30">
<afx-label text = "Url:" data-width= "70"></afx-label>
<afx-label text = "__(Url)" data-width= "70"></afx-label>
<input type = "text" name="url" input-class = "user-input"/>
</afx-hbox>
<afx-label data-height = "30" text = "Short biblio:"/>
<afx-label data-height = "30" text = "__(Short biblio)"/>
<textarea name="shortbiblio" input-class = "user-input"/>
<afx-hbox data-height = "35">
<div></div>
<afx-button iconclass = "fa fa-save" data-id = "bt-user-save" data-width="60" text = "Save"/>
<afx-button iconclass = "fa fa-save" data-id = "bt-user-save" data-width="60" text = "__(Save)"/>
</afx-hbox>
</afx-vbox>
</afx-hbox>
<afx-hbox data-id="cv-container" data-height="100%">
<afx-vbox data-width="150" min-width="100">
<afx-label class = "cat-header" data-height = "23" text = "Categories" iconclass = "fa fa-bars"></afx-label>
<afx-label class = "cat-header" data-height = "23" text = "__(Categories)" iconclass = "fa fa-bars"></afx-label>
<afx-tree-view data-id = "cv-list" ></afx-tree-view>
<afx-hbox data-height="30" class = "cv-side-bar-btn">
<afx-button data-id = "cv-cat-add" data-width = "25" text = "" iconclass = "fa fa-plus-circle"></afx-button>
@ -60,7 +60,7 @@
<div data-id = "editor-container">
<textarea data-id="markarea" ></textarea>
</div>
<afx-label text = "Tags:" style="font-weight:bold;" data-height="25" ></afx-label>
<afx-label text = "__(Tags)" style="font-weight:bold;" data-height="25" ></afx-label>
<afx-hbox data-height="25">
<input type = "text" data-id = "input-tags" />
<div data-width="5"></div>

View File

@ -0,0 +1,11 @@
coffee_files = main.coffee
jsfiles = blockly/blockly_compressed.js blockly/en.js blockly/blocks_compressed.js blockly/javascript_compressed.js
cssfiles =
copyfiles = scheme.html package.json
PKG_NAME=CodeBlock
include ../pkg.mk

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,164 @@
// Do not edit this file; automatically generated by build.py.
'use strict';
Blockly.Blocks.colour={};Blockly.Constants={};Blockly.Constants.Colour={};Blockly.Constants.Colour.HUE=20;Blockly.Blocks.colour.HUE=Blockly.Constants.Colour.HUE;
Blockly.defineBlocksWithJsonArray([{type:"colour_picker",message0:"%1",args0:[{type:"field_colour",name:"COLOUR",colour:"#ff0000"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_PICKER_HELPURL}",tooltip:"%{BKY_COLOUR_PICKER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"colour_random",message0:"%{BKY_COLOUR_RANDOM_TITLE}",output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RANDOM_HELPURL}",tooltip:"%{BKY_COLOUR_RANDOM_TOOLTIP}"},{type:"colour_rgb",message0:"%{BKY_COLOUR_RGB_TITLE} %{BKY_COLOUR_RGB_RED} %1 %{BKY_COLOUR_RGB_GREEN} %2 %{BKY_COLOUR_RGB_BLUE} %3",
args0:[{type:"input_value",name:"RED",check:"Number",align:"RIGHT"},{type:"input_value",name:"GREEN",check:"Number",align:"RIGHT"},{type:"input_value",name:"BLUE",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_RGB_HELPURL}",tooltip:"%{BKY_COLOUR_RGB_TOOLTIP}"},{type:"colour_blend",message0:"%{BKY_COLOUR_BLEND_TITLE} %{BKY_COLOUR_BLEND_COLOUR1} %1 %{BKY_COLOUR_BLEND_COLOUR2} %2 %{BKY_COLOUR_BLEND_RATIO} %3",args0:[{type:"input_value",name:"COLOUR1",
check:"Colour",align:"RIGHT"},{type:"input_value",name:"COLOUR2",check:"Colour",align:"RIGHT"},{type:"input_value",name:"RATIO",check:"Number",align:"RIGHT"}],output:"Colour",colour:"%{BKY_COLOUR_HUE}",helpUrl:"%{BKY_COLOUR_BLEND_HELPURL}",tooltip:"%{BKY_COLOUR_BLEND_TOOLTIP}"}]);Blockly.Blocks.lists={};Blockly.Constants.Lists={};Blockly.Constants.Lists.HUE=260;Blockly.Blocks.lists.HUE=Blockly.Constants.Lists.HUE;
Blockly.defineBlocksWithJsonArray([{type:"lists_create_empty",message0:"%{BKY_LISTS_CREATE_EMPTY_TITLE}",output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_CREATE_EMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_CREATE_EMPTY_HELPURL}"},{type:"lists_repeat",message0:"%{BKY_LISTS_REPEAT_TITLE}",args0:[{type:"input_value",name:"ITEM"},{type:"input_value",name:"NUM",check:"Number"}],output:"Array",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_LISTS_REPEAT_HELPURL}"},{type:"lists_reverse",
message0:"%{BKY_LISTS_REVERSE_MESSAGE0}",args0:[{type:"input_value",name:"LIST",check:"Array"}],output:"Array",inputsInline:!0,colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_REVERSE_TOOLTIP}",helpUrl:"%{BKY_LISTS_REVERSE_HELPURL}"},{type:"lists_isEmpty",message0:"%{BKY_LISTS_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Boolean",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_LISTS_ISEMPTY_HELPURL}"},{type:"lists_length",
message0:"%{BKY_LISTS_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_LISTS_HUE}",tooltip:"%{BKY_LISTS_LENGTH_TOOLTIP}",helpUrl:"%{BKY_LISTS_LENGTH_HELPURL}"}]);
Blockly.Blocks.lists_create_with={init:function(){this.setHelpUrl(Blockly.Msg.LISTS_CREATE_WITH_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.itemCount_=3;this.updateShape_();this.setOutput(!0,"Array");this.setMutator(new Blockly.Mutator(["lists_create_with_item"]));this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),
10);this.updateShape_()},decompose:function(a){var b=a.newBlock("lists_create_with_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("lists_create_with_item");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;
c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||
this.appendDummyInput("EMPTY").appendField(Blockly.Msg.LISTS_CREATE_EMPTY_TITLE);for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH)}for(;this.getInput("ADD"+a);)this.removeInput("ADD"+a),a++}};
Blockly.Blocks.lists_create_with_container={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD);this.appendStatementInput("STACK");this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.lists_create_with_item={init:function(){this.setColour(Blockly.Blocks.lists.HUE);this.appendDummyInput().appendField(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.lists_indexOf={init:function(){var a=[[Blockly.Msg.LISTS_INDEX_OF_FIRST,"FIRST"],[Blockly.Msg.LISTS_INDEX_OF_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_INDEX_OF_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.setOutput(!0,"Number");this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST);this.appendValueInput("FIND").appendField(new Blockly.FieldDropdown(a),"END");this.setInputsInline(!0);var b=this;this.setTooltip(function(){return Blockly.Msg.LISTS_INDEX_OF_TOOLTIP.replace("%1",
b.workspace.options.oneBasedIndex?"0":"-1")})}};
Blockly.Blocks.lists_getIndex={init:function(){var a=[[Blockly.Msg.LISTS_GET_INDEX_GET,"GET"],[Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE,"GET_REMOVE"],[Blockly.Msg.LISTS_GET_INDEX_REMOVE,"REMOVE"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
a=new Blockly.FieldDropdown(a,function(a){this.sourceBlock_.updateStatement_("REMOVE"==a)});this.appendValueInput("VALUE").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST);this.appendDummyInput().appendField(a,"MODE").appendField("","SPACE");this.appendDummyInput("AT");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_INDEX_TAIL);this.setInputsInline(!0);this.setOutput(!0);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=
b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "GET FROM_START":case "GET FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM;break;case "GET FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST;break;case "GET LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST;break;case "GET RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM;break;case "GET_REMOVE FROM_START":case "GET_REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM;break;case "GET_REMOVE FIRST":e=
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST;break;case "GET_REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST;break;case "GET_REMOVE RANDOM":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM;break;case "REMOVE FROM_START":case "REMOVE FROM_END":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM;break;case "REMOVE FIRST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST;break;case "REMOVE LAST":e=Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST;break;case "REMOVE RANDOM":e=
Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+("FROM_START"==d?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP).replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("statement",!this.outputConnection);var b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){var b="true"==
a.getAttribute("statement");this.updateStatement_(b);a="false"!=a.getAttribute("at");this.updateAt_(a)},updateStatement_:function(a){a!=!this.outputConnection&&(this.unplug(!0,!0),a?(this.setOutput(!1),this.setPreviousStatement(!0),this.setNextStatement(!0)):(this.setPreviousStatement(!1),this.setNextStatement(!1),this.setOutput(!0)))},updateAt_:function(a){this.removeInput("AT");this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.getInput("AT").appendField(b,"WHERE");Blockly.Msg.LISTS_GET_INDEX_TAIL&&this.moveInputBefore("TAIL",null)}};
Blockly.Blocks.lists_setIndex={init:function(){var a=[[Blockly.Msg.LISTS_SET_INDEX_SET,"SET"],[Blockly.Msg.LISTS_SET_INDEX_INSERT,"INSERT"]];this.WHERE_OPTIONS=[[Blockly.Msg.LISTS_GET_INDEX_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_INDEX_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_INDEX_FIRST,"FIRST"],[Blockly.Msg.LISTS_GET_INDEX_LAST,"LAST"],[Blockly.Msg.LISTS_GET_INDEX_RANDOM,"RANDOM"]];this.setHelpUrl(Blockly.Msg.LISTS_SET_INDEX_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST);
this.appendDummyInput().appendField(new Blockly.FieldDropdown(a),"MODE").appendField("","SPACE");this.appendDummyInput("AT");this.appendValueInput("TO").appendField(Blockly.Msg.LISTS_SET_INDEX_INPUT_TO);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setTooltip(Blockly.Msg.LISTS_SET_INDEX_TOOLTIP);this.updateAt_(!0);var b=this;this.setTooltip(function(){var a=b.getFieldValue("MODE"),d=b.getFieldValue("WHERE"),e="";switch(a+" "+d){case "SET FROM_START":case "SET FROM_END":e=
Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM;break;case "SET FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST;break;case "SET LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST;break;case "SET RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM;break;case "INSERT FROM_START":case "INSERT FROM_END":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM;break;case "INSERT FIRST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST;break;case "INSERT LAST":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST;
break;case "INSERT RANDOM":e=Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM}if("FROM_START"==d||"FROM_END"==d)e+=" "+Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP.replace("%1",b.workspace.options.oneBasedIndex?"#1":"#0");return e})},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT").type==Blockly.INPUT_VALUE;a.setAttribute("at",b);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT");
this.removeInput("ORDINAL",!0);a?(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):this.appendDummyInput("AT");var b=new Blockly.FieldDropdown(this.WHERE_OPTIONS,function(b){var c="FROM_START"==b||"FROM_END"==b;if(c!=a){var e=this.sourceBlock_;e.updateAt_(c);e.setFieldValue(b,"WHERE");return null}});this.moveInputBefore("AT","TO");this.getInput("ORDINAL")&&this.moveInputBefore("ORDINAL",
"TO");this.getInput("AT").appendField(b,"WHERE")}};
Blockly.Blocks.lists_getSublist={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START,"FROM_START"],[Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END,"FROM_END"],[Blockly.Msg.LISTS_GET_SUBLIST_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.LISTS_GET_SUBLIST_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);
this.appendValueInput("LIST").setCheck("Array").appendField(Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.LISTS_GET_SUBLIST_TAIL);this.setInputsInline(!0);this.setOutput(!0,"Array");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),b=this.getInput("AT1").type==
Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
this.appendDummyInput("AT"+a);var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&(this.moveInputBefore("AT1","AT2"),this.getInput("ORDINAL1")&&this.moveInputBefore("ORDINAL1","AT2"));Blockly.Msg.LISTS_GET_SUBLIST_TAIL&&this.moveInputBefore("TAIL",null)}};
Blockly.Blocks.lists_sort={init:function(){this.jsonInit({message0:Blockly.Msg.LISTS_SORT_TITLE,args0:[{type:"field_dropdown",name:"TYPE",options:[[Blockly.Msg.LISTS_SORT_TYPE_NUMERIC,"NUMERIC"],[Blockly.Msg.LISTS_SORT_TYPE_TEXT,"TEXT"],[Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE,"IGNORE_CASE"]]},{type:"field_dropdown",name:"DIRECTION",options:[[Blockly.Msg.LISTS_SORT_ORDER_ASCENDING,"1"],[Blockly.Msg.LISTS_SORT_ORDER_DESCENDING,"-1"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Array",colour:Blockly.Blocks.lists.HUE,
tooltip:Blockly.Msg.LISTS_SORT_TOOLTIP,helpUrl:Blockly.Msg.LISTS_SORT_HELPURL})}};
Blockly.Blocks.lists_split={init:function(){var a=this,b=new Blockly.FieldDropdown([[Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT,"SPLIT"],[Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST,"JOIN"]],function(b){a.updateType_(b)});this.setHelpUrl(Blockly.Msg.LISTS_SPLIT_HELPURL);this.setColour(Blockly.Blocks.lists.HUE);this.appendValueInput("INPUT").setCheck("String").appendField(b,"MODE");this.appendValueInput("DELIM").setCheck("String").appendField(Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER);this.setInputsInline(!0);
this.setOutput(!0,"Array");this.setTooltip(function(){var b=a.getFieldValue("MODE");if("SPLIT"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT;if("JOIN"==b)return Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN;throw"Unknown mode: "+b;})},updateType_:function(a){"SPLIT"==a?(this.outputConnection.setCheck("Array"),this.getInput("INPUT").setCheck("String")):(this.outputConnection.setCheck("String"),this.getInput("INPUT").setCheck("Array"))},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("mode",
this.getFieldValue("MODE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("mode"))}};Blockly.Blocks.logic={};Blockly.Constants.Logic={};Blockly.Constants.Logic.HUE=210;Blockly.Blocks.logic.HUE=Blockly.Constants.Logic.HUE;
Blockly.defineBlocksWithJsonArray([{type:"logic_boolean",message0:"%1",args0:[{type:"field_dropdown",name:"BOOL",options:[["%{BKY_LOGIC_BOOLEAN_TRUE}","TRUE"],["%{BKY_LOGIC_BOOLEAN_FALSE}","FALSE"]]}],output:"Boolean",colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_BOOLEAN_TOOLTIP}",helpUrl:"%{BKY_LOGIC_BOOLEAN_HELPURL}"},{type:"controls_if",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",
name:"DO0"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",mutator:"controls_if_mutator",extensions:["controls_if_tooltip"]},{type:"controls_ifelse",message0:"%{BKY_CONTROLS_IF_MSG_IF} %1",args0:[{type:"input_value",name:"IF0",check:"Boolean"}],message1:"%{BKY_CONTROLS_IF_MSG_THEN} %1",args1:[{type:"input_statement",name:"DO0"}],message2:"%{BKY_CONTROLS_IF_MSG_ELSE} %1",args2:[{type:"input_statement",name:"ELSE"}],previousStatement:null,nextStatement:null,
colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKYCONTROLS_IF_TOOLTIP_2}",helpUrl:"%{BKY_CONTROLS_IF_HELPURL}",extensions:["controls_if_tooltip"]},{type:"logic_compare",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A"},{type:"field_dropdown",name:"OP",options:[["=","EQ"],["\u2260","NEQ"],["<","LT"],["\u2264","LTE"],[">","GT"],["\u2265","GTE"]]},{type:"input_value",name:"B"}],inputsInline:!0,output:"Boolean",colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_COMPARE_HELPURL}",extensions:["logic_compare",
"logic_op_tooltip"]},{type:"logic_operation",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Boolean"},{type:"field_dropdown",name:"OP",options:[["%{BKY_LOGIC_OPERATION_AND}","AND"],["%{BKY_LOGIC_OPERATION_OR}","OR"]]},{type:"input_value",name:"B",check:"Boolean"}],inputsInline:!0,output:"Boolean",colour:"%{BKY_LOGIC_HUE}",helpUrl:"%{BKY_LOGIC_OPERATION_HELPURL}",extensions:["logic_op_tooltip"]},{type:"logic_negate",message0:"%{BKY_LOGIC_NEGATE_TITLE}",args0:[{type:"input_value",name:"BOOL",
check:"Boolean"}],output:"Boolean",colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NEGATE_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NEGATE_HELPURL}"},{type:"logic_null",message0:"%{BKY_LOGIC_NULL}",output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_NULL_TOOLTIP}",helpUrl:"%{BKY_LOGIC_NULL_HELPURL}"},{type:"logic_ternary",message0:"%{BKY_LOGIC_TERNARY_CONDITION} %1",args0:[{type:"input_value",name:"IF",check:"Boolean"}],message1:"%{BKY_LOGIC_TERNARY_IF_TRUE} %1",args1:[{type:"input_value",name:"THEN"}],
message2:"%{BKY_LOGIC_TERNARY_IF_FALSE} %1",args2:[{type:"input_value",name:"ELSE"}],output:null,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_LOGIC_TERNARY_TOOLTIP}",helpUrl:"%{BKY_LOGIC_TERNARY_HELPURL}",extensions:["logic_ternary"]}]);
Blockly.defineBlocksWithJsonArray([{type:"controls_if_if",message0:"%{BKY_CONTROLS_IF_IF_TITLE_IF}",nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_IF_TOOLTIP}"},{type:"controls_if_elseif",message0:"%{BKY_CONTROLS_IF_ELSEIF_TITLE_ELSEIF}",previousStatement:null,nextStatement:null,enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSEIF_TOOLTIP}"},{type:"controls_if_else",message0:"%{BKY_CONTROLS_IF_ELSE_TITLE_ELSE}",previousStatement:null,
enableContextMenu:!1,colour:"%{BKY_LOGIC_HUE}",tooltip:"%{BKY_CONTROLS_IF_ELSE_TOOLTIP}"}]);Blockly.Constants.Logic.TOOLTIPS_BY_OP={EQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_EQ}",NEQ:"%{BKY_LOGIC_COMPARE_TOOLTIP_NEQ}",LT:"%{BKY_LOGIC_COMPARE_TOOLTIP_LT}",LTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_LTE}",GT:"%{BKY_LOGIC_COMPARE_TOOLTIP_GT}",GTE:"%{BKY_LOGIC_COMPARE_TOOLTIP_GTE}",AND:"%{BKY_LOGIC_OPERATION_TOOLTIP_AND}",OR:"%{BKY_LOGIC_OPERATION_TOOLTIP_OR}"};
Blockly.Extensions.register("logic_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Logic.TOOLTIPS_BY_OP));
Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN={elseifCount_:0,elseCount_:0,mutationToDom:function(){if(!this.elseifCount_&&!this.elseCount_)return null;var a=document.createElement("mutation");this.elseifCount_&&a.setAttribute("elseif",this.elseifCount_);this.elseCount_&&a.setAttribute("else",1);return a},domToMutation:function(a){this.elseifCount_=parseInt(a.getAttribute("elseif"),10)||0;this.elseCount_=parseInt(a.getAttribute("else"),10)||0;this.updateShape_()},decompose:function(a){var b=a.newBlock("controls_if_if");
b.initSvg();for(var c=b.nextConnection,d=1;d<=this.elseifCount_;d++){var e=a.newBlock("controls_if_elseif");e.initSvg();c.connect(e.previousConnection);c=e.nextConnection}this.elseCount_&&(a=a.newBlock("controls_if_else"),a.initSvg(),c.connect(a.previousConnection));return b},compose:function(a){var b=a.nextConnection.targetBlock();this.elseCount_=this.elseifCount_=0;a=[null];for(var c=[null],d=null;b;){switch(b.type){case "controls_if_elseif":this.elseifCount_++;a.push(b.valueConnection_);c.push(b.statementConnection_);
break;case "controls_if_else":this.elseCount_++;d=b.statementConnection_;break;default:throw"Unknown block type.";}b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateShape_();for(b=1;b<=this.elseifCount_;b++)Blockly.Mutator.reconnect(a[b],this,"IF"+b),Blockly.Mutator.reconnect(c[b],this,"DO"+b);Blockly.Mutator.reconnect(d,this,"ELSE")},saveConnections:function(a){a=a.nextConnection.targetBlock();for(var b=1;a;){switch(a.type){case "controls_if_elseif":var c=this.getInput("IF"+b),d=this.getInput("DO"+
b);a.valueConnection_=c&&c.connection.targetConnection;a.statementConnection_=d&&d.connection.targetConnection;b++;break;case "controls_if_else":d=this.getInput("ELSE");a.statementConnection_=d&&d.connection.targetConnection;break;default:throw"Unknown block type.";}a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.getInput("ELSE")&&this.removeInput("ELSE");for(var a=1;this.getInput("IF"+a);)this.removeInput("IF"+a),this.removeInput("DO"+a),a++;for(a=1;a<=this.elseifCount_;a++)this.appendValueInput("IF"+
a).setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSEIF),this.appendStatementInput("DO"+a).appendField(Blockly.Msg.CONTROLS_IF_MSG_THEN);this.elseCount_&&this.appendStatementInput("ELSE").appendField(Blockly.Msg.CONTROLS_IF_MSG_ELSE)}};Blockly.Extensions.registerMutator("controls_if_mutator",Blockly.Constants.Logic.CONTROLS_IF_MUTATOR_MIXIN,null,["controls_if_elseif","controls_if_else"]);
Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){if(this.elseifCount_||this.elseCount_){if(!this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_2;if(this.elseifCount_&&!this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_3;if(this.elseifCount_&&this.elseCount_)return Blockly.Msg.CONTROLS_IF_TOOLTIP_4}else return Blockly.Msg.CONTROLS_IF_TOOLTIP_1;return""}.bind(this))};Blockly.Extensions.register("controls_if_tooltip",Blockly.Constants.Logic.CONTROLS_IF_TOOLTIP_EXTENSION);
Blockly.Constants.Logic.fixLogicCompareRtlOpLabels=function(){var a={LT:"\u200f<\u200f",LTE:"\u200f\u2264\u200f",GT:"\u200f>\u200f",GTE:"\u200f\u2265\u200f"},b=this.getField("OP");if(b){b=b.getOptions();for(var c=0;c<b.length;++c){var d=b[c],e=a[d[1]];goog.isString(d[0])&&e&&(d[0]=e)}}};
Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN={prevBlocks_:[null,null],onchange:function(a){var b=this.getInputTargetBlock("A"),c=this.getInputTargetBlock("B");if(b&&c&&!b.outputConnection.checkType_(c.outputConnection)){Blockly.Events.setGroup(a.group);for(a=0;a<this.prevBlocks_.length;a++){var d=this.prevBlocks_[a];if(d===b||d===c)d.unplug(),d.bumpNeighbours_()}Blockly.Events.setGroup(!1)}this.prevBlocks_[0]=b;this.prevBlocks_[1]=c}};
Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION=function(){this.RTL&&Blockly.Constants.Logic.fixLogicCompareRtlOpLabels.apply(this);this.mixin(Blockly.Constants.Logic.LOGIC_COMPARE_ONCHANGE_MIXIN)};Blockly.Extensions.register("logic_compare",Blockly.Constants.Logic.LOGIC_COMPARE_EXTENSION);
Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN={prevParentConnection_:null,onchange:function(a){var b=this.getInputTargetBlock("THEN"),c=this.getInputTargetBlock("ELSE"),d=this.outputConnection.targetConnection;if((b||c)&&d)for(var e=0;2>e;e++){var f=1==e?b:c;f&&!f.outputConnection.checkType_(d)&&(Blockly.Events.setGroup(a.group),d===this.prevParentConnection_?(this.unplug(),d.getSourceBlock().bumpNeighbours_()):(f.unplug(),f.bumpNeighbours_()),Blockly.Events.setGroup(!1))}this.prevParentConnection_=
d}};Blockly.Extensions.registerMixin("logic_ternary",Blockly.Constants.Logic.LOGIC_TERNARY_ONCHANGE_MIXIN);Blockly.Blocks.loops={};Blockly.Constants.Loops={};Blockly.Constants.Loops.HUE=120;Blockly.Blocks.loops.HUE=Blockly.Constants.Loops.HUE;
Blockly.defineBlocksWithJsonArray([{type:"controls_repeat_ext",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"input_value",name:"TIMES",check:"Number"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_repeat",message0:"%{BKY_CONTROLS_REPEAT_TITLE}",args0:[{type:"field_number",name:"TIMES",
value:10,min:0,precision:1}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",tooltip:"%{BKY_CONTROLS_REPEAT_TOOLTIP}",helpUrl:"%{BKY_CONTROLS_REPEAT_HELPURL}"},{type:"controls_whileUntil",message0:"%1 %2",args0:[{type:"field_dropdown",name:"MODE",options:[["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_WHILE}","WHILE"],["%{BKY_CONTROLS_WHILEUNTIL_OPERATOR_UNTIL}","UNTIL"]]},{type:"input_value",name:"BOOL",
check:"Boolean"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_WHILEUNTIL_HELPURL}",extensions:["controls_whileUntil_tooltip"]},{type:"controls_for",message0:"%{BKY_CONTROLS_FOR_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"FROM",check:"Number",align:"RIGHT"},{type:"input_value",name:"TO",check:"Number",align:"RIGHT"},{type:"input_value",
name:"BY",check:"Number",align:"RIGHT"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",args1:[{type:"input_statement",name:"DO"}],inputsInline:!0,previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOR_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_for_tooltip"]},{type:"controls_forEach",message0:"%{BKY_CONTROLS_FOREACH_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:null},{type:"input_value",name:"LIST",check:"Array"}],message1:"%{BKY_CONTROLS_REPEAT_INPUT_DO} %1",
args1:[{type:"input_statement",name:"DO"}],previousStatement:null,nextStatement:null,colour:"%{BKY_LOOPS_HUE}",helpUrl:"%{BKY_CONTROLS_FOREACH_HELPURL}",extensions:["contextMenu_newGetVariableBlock","controls_forEach_tooltip"]},{type:"controls_flow_statements",message0:"%1",args0:[{type:"field_dropdown",name:"FLOW",options:[["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK}","BREAK"],["%{BKY_CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE}","CONTINUE"]]}],previousStatement:null,colour:"%{BKY_LOOPS_HUE}",
helpUrl:"%{BKY_CONTROLS_FLOW_STATEMENTS_HELPURL}",extensions:["controls_flow_tooltip","controls_flow_in_loop_check"]}]);Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS={WHILE:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_WHILE}",UNTIL:"%{BKY_CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL}"};Blockly.Extensions.register("controls_whileUntil_tooltip",Blockly.Extensions.buildTooltipForDropdown("MODE",Blockly.Constants.Loops.WHILE_UNTIL_TOOLTIPS));
Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS={BREAK:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK}",CONTINUE:"%{BKY_CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE}"};Blockly.Extensions.register("controls_flow_tooltip",Blockly.Extensions.buildTooltipForDropdown("FLOW",Blockly.Constants.Loops.BREAK_CONTINUE_TOOLTIPS));
Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN={customContextMenu:function(a){var b=this.getFieldValue("VAR");if(!this.isCollapsed()&&null!=b){var c={enabled:!0};c.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",b);b=goog.dom.createDom("field",null,b);b.setAttribute("name","VAR");b=goog.dom.createDom("block",null,b);b.setAttribute("type","variables_get");c.callback=Blockly.ContextMenu.callbackFactory(this,b);a.push(c)}}};
Blockly.Extensions.registerMixin("contextMenu_newGetVariableBlock",Blockly.Constants.Loops.CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN);Blockly.Extensions.register("controls_for_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_CONTROLS_FOR_TOOLTIP}","VAR"));Blockly.Extensions.register("controls_forEach_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_CONTROLS_FOREACH_TOOLTIP}","VAR"));
Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN={LOOP_TYPES:["controls_repeat","controls_repeat_ext","controls_forEach","controls_for","controls_whileUntil"],onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.LOOP_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);a?(this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING),this.isInFlyout||
this.getInheritedDisabled()||this.setDisabled(!0))}}};Blockly.Extensions.registerMixin("controls_flow_in_loop_check",Blockly.Constants.Loops.CONTROL_FLOW_IN_LOOP_CHECK_MIXIN);Blockly.Blocks.math={};Blockly.Constants.Math={};Blockly.Constants.Math.HUE=230;Blockly.Blocks.math.HUE=Blockly.Constants.Math.HUE;
Blockly.defineBlocksWithJsonArray([{type:"math_number",message0:"%1",args0:[{type:"field_number",name:"NUM",value:0}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_NUMBER_HELPURL}",tooltip:"%{BKY_MATH_NUMBER_TOOLTIP}",extensions:["parent_tooltip_when_inline"]},{type:"math_arithmetic",message0:"%1 %2 %3",args0:[{type:"input_value",name:"A",check:"Number"},{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ADDITION_SYMBOL}","ADD"],["%{BKY_MATH_SUBTRACTION_SYMBOL}","MINUS"],["%{BKY_MATH_MULTIPLICATION_SYMBOL}",
"MULTIPLY"],["%{BKY_MATH_DIVISION_SYMBOL}","DIVIDE"],["%{BKY_MATH_POWER_SYMBOL}","POWER"]]},{type:"input_value",name:"B",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ARITHMETIC_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_single",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_SINGLE_OP_ROOT}","ROOT"],["%{BKY_MATH_SINGLE_OP_ABSOLUTE}","ABS"],["-","NEG"],["ln","LN"],["log10","LOG10"],["e^","EXP"],["10^","POW10"]]},
{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_SINGLE_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_trig",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_TRIG_SIN}","SIN"],["%{BKY_MATH_TRIG_COS}","COS"],["%{BKY_MATH_TRIG_TAN}","TAN"],["%{BKY_MATH_TRIG_ASIN}","ASIN"],["%{BKY_MATH_TRIG_ACOS}","ACOS"],["%{BKY_MATH_TRIG_ATAN}","ATAN"]]},{type:"input_value",name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",
helpUrl:"%{BKY_MATH_TRIG_HELPURL}",extensions:["math_op_tooltip"]},{type:"math_constant",message0:"%1",args0:[{type:"field_dropdown",name:"CONSTANT",options:[["\u03c0","PI"],["e","E"],["\u03c6","GOLDEN_RATIO"],["sqrt(2)","SQRT2"],["sqrt(\u00bd)","SQRT1_2"],["\u221e","INFINITY"]]}],output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTANT_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTANT_HELPURL}"},{type:"math_number_property",message0:"%1 %2",args0:[{type:"input_value",name:"NUMBER_TO_CHECK",check:"Number"},
{type:"field_dropdown",name:"PROPERTY",options:[["%{BKY_MATH_IS_EVEN}","EVEN"],["%{BKY_MATH_IS_ODD}","ODD"],["%{BKY_MATH_IS_PRIME}","PRIME"],["%{BKY_MATH_IS_WHOLE}","WHOLE"],["%{BKY_MATH_IS_POSITIVE}","POSITIVE"],["%{BKY_MATH_IS_NEGATIVE}","NEGATIVE"],["%{BKY_MATH_IS_DIVISIBLE_BY}","DIVISIBLE_BY"]]}],inputsInline:!0,output:"Boolean",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_IS_TOOLTIP}",mutator:"math_is_divisibleby_mutator"},{type:"math_change",message0:"%{BKY_MATH_CHANGE_TITLE}",args0:[{type:"field_variable",
name:"VAR",variable:"%{BKY_MATH_CHANGE_TITLE_ITEM}"},{type:"input_value",name:"DELTA",check:"Number"}],previousStatement:null,nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_MATH_CHANGE_HELPURL}",extensions:["math_change_tooltip"]},{type:"math_round",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ROUND_OPERATOR_ROUND}","ROUND"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDUP}","ROUNDUP"],["%{BKY_MATH_ROUND_OPERATOR_ROUNDDOWN}","ROUNDDOWN"]]},{type:"input_value",
name:"NUM",check:"Number"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ROUND_HELPURL}",tooltip:"%{BKY_MATH_ROUND_TOOLTIP}"},{type:"math_on_list",message0:"%1 %2",args0:[{type:"field_dropdown",name:"OP",options:[["%{BKY_MATH_ONLIST_OPERATOR_SUM}","SUM"],["%{BKY_MATH_ONLIST_OPERATOR_MIN}","MIN"],["%{BKY_MATH_ONLIST_OPERATOR_MAX}","MAX"],["%{BKY_MATH_ONLIST_OPERATOR_AVERAGE}","AVERAGE"],["%{BKY_MATH_ONLIST_OPERATOR_MEDIAN}","MEDIAN"],["%{BKY_MATH_ONLIST_OPERATOR_MODE}","MODE"],["%{BKY_MATH_ONLIST_OPERATOR_STD_DEV}",
"STD_DEV"],["%{BKY_MATH_ONLIST_OPERATOR_RANDOM}","RANDOM"]]},{type:"input_value",name:"LIST",check:"Array"}],output:"Number",colour:"%{BKY_MATH_HUE}",helpUrl:"%{BKY_MATH_ONLIST_HELPURL}",mutator:"math_modes_of_list_mutator",extensions:["math_op_tooltip"]},{type:"math_modulo",message0:"%{BKY_MATH_MODULO_TITLE}",args0:[{type:"input_value",name:"DIVIDEND",check:"Number"},{type:"input_value",name:"DIVISOR",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_MODULO_TOOLTIP}",
helpUrl:"%{BKY_MATH_MODULO_HELPURL}"},{type:"math_constrain",message0:"%{BKY_MATH_CONSTRAIN_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"Number"},{type:"input_value",name:"LOW",check:"Number"},{type:"input_value",name:"HIGH",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_CONSTRAIN_TOOLTIP}",helpUrl:"%{BKY_MATH_CONSTRAIN_HELPURL}"},{type:"math_random_int",message0:"%{BKY_MATH_RANDOM_INT_TITLE}",args0:[{type:"input_value",name:"FROM",check:"Number"},
{type:"input_value",name:"TO",check:"Number"}],inputsInline:!0,output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_INT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_INT_HELPURL}"},{type:"math_random_float",message0:"%{BKY_MATH_RANDOM_FLOAT_TITLE_RANDOM}",output:"Number",colour:"%{BKY_MATH_HUE}",tooltip:"%{BKY_MATH_RANDOM_FLOAT_TOOLTIP}",helpUrl:"%{BKY_MATH_RANDOM_FLOAT_HELPURL}"}]);
Blockly.Constants.Math.TOOLTIPS_BY_OP={ADD:"%{BKY_MATH_ARITHMETIC_TOOLTIP_ADD}",MINUS:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MINUS}",MULTIPLY:"%{BKY_MATH_ARITHMETIC_TOOLTIP_MULTIPLY}",DIVIDE:"%{BKY_MATH_ARITHMETIC_TOOLTIP_DIVIDE}",POWER:"%{BKY_MATH_ARITHMETIC_TOOLTIP_POWER}",ROOT:"%{BKY_MATH_SINGLE_TOOLTIP_ROOT}",ABS:"%{BKY_MATH_SINGLE_TOOLTIP_ABS}",NEG:"%{BKY_MATH_SINGLE_TOOLTIP_NEG}",LN:"%{BKY_MATH_SINGLE_TOOLTIP_LN}",LOG10:"%{BKY_MATH_SINGLE_TOOLTIP_LOG10}",EXP:"%{BKY_MATH_SINGLE_TOOLTIP_EXP}",POW10:"%{BKY_MATH_SINGLE_TOOLTIP_POW10}",
SIN:"%{BKY_MATH_TRIG_TOOLTIP_SIN}",COS:"%{BKY_MATH_TRIG_TOOLTIP_COS}",TAN:"%{BKY_MATH_TRIG_TOOLTIP_TAN}",ASIN:"%{BKY_MATH_TRIG_TOOLTIP_ASIN}",ACOS:"%{BKY_MATH_TRIG_TOOLTIP_ACOS}",ATAN:"%{BKY_MATH_TRIG_TOOLTIP_ATAN}",SUM:"%{BKY_MATH_ONLIST_TOOLTIP_SUM}",MIN:"%{BKY_MATH_ONLIST_TOOLTIP_MIN}",MAX:"%{BKY_MATH_ONLIST_TOOLTIP_MAX}",AVERAGE:"%{BKY_MATH_ONLIST_TOOLTIP_AVERAGE}",MEDIAN:"%{BKY_MATH_ONLIST_TOOLTIP_MEDIAN}",MODE:"%{BKY_MATH_ONLIST_TOOLTIP_MODE}",STD_DEV:"%{BKY_MATH_ONLIST_TOOLTIP_STD_DEV}",RANDOM:"%{BKY_MATH_ONLIST_TOOLTIP_RANDOM}"};
Blockly.Extensions.register("math_op_tooltip",Blockly.Extensions.buildTooltipForDropdown("OP",Blockly.Constants.Math.TOOLTIPS_BY_OP));
Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation"),b="DIVISIBLE_BY"==this.getFieldValue("PROPERTY");a.setAttribute("divisor_input",b);return a},domToMutation:function(a){a="true"==a.getAttribute("divisor_input");this.updateShape_(a)},updateShape_:function(a){var b=this.getInput("DIVISOR");a?b||this.appendValueInput("DIVISOR").setCheck("Number"):b&&this.removeInput("DIVISOR")}};
Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION=function(){this.getField("PROPERTY").setValidator(function(a){this.sourceBlock_.updateShape_("DIVISIBLE_BY"==a)})};Blockly.Extensions.registerMutator("math_is_divisibleby_mutator",Blockly.Constants.Math.IS_DIVISIBLEBY_MUTATOR_MIXIN,Blockly.Constants.Math.IS_DIVISIBLE_MUTATOR_EXTENSION);Blockly.Constants.Math.CHANGE_TOOLTIP_EXTENSION=function(){this.setTooltip(function(){return Blockly.Msg.MATH_CHANGE_TOOLTIP.replace("%1",this.getFieldValue("VAR"))}.bind(this))};
Blockly.Extensions.register("math_change_tooltip",Blockly.Extensions.buildTooltipWithFieldValue("%{BKY_MATH_CHANGE_TOOLTIP}","VAR"));Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN={updateType_:function(a){"MODE"==a?this.outputConnection.setCheck("Array"):this.outputConnection.setCheck("Number")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("op",this.getFieldValue("OP"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("op"))}};
Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION=function(){this.getField("OP").setValidator(function(a){this.updateType_(a)}.bind(this))};Blockly.Extensions.registerMutator("math_modes_of_list_mutator",Blockly.Constants.Math.LIST_MODES_MUTATOR_MIXIN,Blockly.Constants.Math.LIST_MODES_MUTATOR_EXTENSION);Blockly.Blocks.procedures={};Blockly.Blocks.procedures.HUE=290;
Blockly.Blocks.procedures_defnoreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT&&
this.setCommentText(Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:function(a){this.hasStatements_!==a&&(a?(this.appendStatementInput("STACK").appendField(Blockly.Msg.PROCEDURES_DEFNORETURN_DO),this.getInput("RETURN")&&this.moveInputBefore("STACK",
"RETURN")):this.removeInput("STACK",!0),this.hasStatements_=a)},updateParams_:function(){for(var a=!1,b={},c=0;c<this.arguments_.length;c++){if(b["arg_"+this.arguments_[c].toLowerCase()]){a=!0;break}b["arg_"+this.arguments_[c].toLowerCase()]=!0}a?this.setWarningText(Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING):this.setWarningText(null);a="";this.arguments_.length&&(a=Blockly.Msg.PROCEDURES_BEFORE_PARAMS+" "+this.arguments_.join(", "));Blockly.Events.disable();try{this.setFieldValue(a,"PARAMS")}finally{Blockly.Events.enable()}},
mutationToDom:function(a){var b=document.createElement("mutation");a&&b.setAttribute("name",this.getFieldValue("NAME"));for(var c=0;c<this.argumentVarModels_.length;c++){var d=document.createElement("arg"),e=this.argumentVarModels_[c];d.setAttribute("name",e.name);d.setAttribute("varId",e.getId());a&&this.paramIds_&&d.setAttribute("paramId",this.paramIds_[c]);b.appendChild(d)}this.hasStatements_||b.setAttribute("statements","false");return b},domToMutation:function(a){this.arguments_=[];this.argumentVarModels_=
[];for(var b=0,c;c=a.childNodes[b];b++)if("arg"==c.nodeName.toLowerCase()){var d=c.getAttribute("name");c=c.getAttribute("varId");this.arguments_.push(d);d=Blockly.Variables.getOrCreateVariablePackage(this.workspace,c,d,"");this.argumentVarModels_.push(d)}this.updateParams_();Blockly.Procedures.mutateCallers(this);this.setStatements_("false"!==a.getAttribute("statements"))},decompose:function(a){var b=a.newBlock("procedures_mutatorcontainer");b.initSvg();this.getInput("RETURN")?b.setFieldValue(this.hasStatements_?
"TRUE":"FALSE","STATEMENTS"):b.getInput("STATEMENT_INPUT").setVisible(!1);for(var c=b.getInput("STACK").connection,d=0;d<this.arguments_.length;d++){var e=a.newBlock("procedures_mutatorarg");e.initSvg();e.setFieldValue(this.arguments_[d],"NAME");e.oldLocation=d;c.connect(e.previousConnection);c=e.nextConnection}Blockly.Procedures.mutateCallers(this);return b},compose:function(a){this.arguments_=[];this.paramIds_=[];this.argumentVarModels_=[];for(var b=a.getInputTargetBlock("STACK");b;){var c=b.getFieldValue("NAME");
this.arguments_.push(c);c=this.workspace.getVariable(c,"");this.argumentVarModels_.push(c);this.paramIds_.push(b.id);b=b.nextConnection&&b.nextConnection.targetBlock()}this.updateParams_();Blockly.Procedures.mutateCallers(this);a=a.getFieldValue("STATEMENTS");if(null!==a&&(a="TRUE"==a,this.hasStatements_!=a))if(a)this.setStatements_(!0),Blockly.Mutator.reconnect(this.statementConnection_,this,"STACK"),this.statementConnection_=null;else{a=this.getInput("STACK").connection;if(this.statementConnection_=
a.targetConnection)a=a.targetBlock(),a.unplug(),a.bumpNeighbours_();this.setStatements_(!1)}},getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!1]},getVars:function(){return this.arguments_},getVarModels:function(){return this.argumentVarModels_},renameVarById:function(a,b){var c=this.workspace.getVariableById(a);if(""==c.type){c=c.name;for(var d=this.workspace.getVariableById(b),e=!1,f=0;f<this.argumentVarModels_.length;f++)this.argumentVarModels_[f].getId()==a&&(this.arguments_[f]=
d.name,this.argumentVarModels_[f]=d,e=!0);e&&this.displayRenamedVar_(c,d.name)}},updateVarName:function(a){for(var b=a.name,c=!1,d=0;d<this.argumentVarModels_.length;d++)if(this.argumentVarModels_[d].getId()==a.getId()){var e=this.arguments_[d];this.arguments_[d]=b;c=!0}c&&this.displayRenamedVar_(e,b)},displayRenamedVar_:function(a,b){this.updateParams_();if(this.mutator.isVisible())for(var c=this.mutator.workspace_.getAllBlocks(),d=0,e;e=c[d];d++)"procedures_mutatorarg"==e.type&&Blockly.Names.equals(a,
e.getFieldValue("NAME"))&&e.setFieldValue(b,"NAME")},customContextMenu:function(a){var b={enabled:!0},c=this.getFieldValue("NAME");b.text=Blockly.Msg.PROCEDURES_CREATE_DO.replace("%1",c);var d=goog.dom.createDom("mutation");d.setAttribute("name",c);for(var e=0;e<this.arguments_.length;e++)c=goog.dom.createDom("arg"),c.setAttribute("name",this.arguments_[e]),d.appendChild(c);d=goog.dom.createDom("block",null,d);d.setAttribute("type",this.callType_);b.callback=Blockly.ContextMenu.callbackFactory(this,
d);a.push(b);if(!this.isCollapsed())for(e=0;e<this.arguments_.length;e++)b={enabled:!0},c=this.arguments_[e],b.text=Blockly.Msg.VARIABLES_SET_CREATE_GET.replace("%1",c),d=goog.dom.createDom("field",null,c),d.setAttribute("name","VAR"),d=goog.dom.createDom("block",null,d),d.setAttribute("type","variables_get"),b.callback=Blockly.ContextMenu.callbackFactory(this,d),a.push(b)},callType_:"procedures_callnoreturn"};
Blockly.Blocks.procedures_defreturn={init:function(){var a=new Blockly.FieldTextInput("",Blockly.Procedures.rename);a.setSpellcheck(!1);this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_DEFRETURN_TITLE).appendField(a,"NAME").appendField("","PARAMS");this.appendValueInput("RETURN").setAlign(Blockly.ALIGN_RIGHT).appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setMutator(new Blockly.Mutator(["procedures_mutatorarg"]));(this.workspace.options.comments||this.workspace.options.parentWorkspace&&
this.workspace.options.parentWorkspace.options.comments)&&Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT&&this.setCommentText(Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.setStatements_(!0);this.statementConnection_=null},setStatements_:Blockly.Blocks.procedures_defnoreturn.setStatements_,updateParams_:Blockly.Blocks.procedures_defnoreturn.updateParams_,
mutationToDom:Blockly.Blocks.procedures_defnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_defnoreturn.domToMutation,decompose:Blockly.Blocks.procedures_defnoreturn.decompose,compose:Blockly.Blocks.procedures_defnoreturn.compose,getProcedureDef:function(){return[this.getFieldValue("NAME"),this.arguments_,!0]},getVars:Blockly.Blocks.procedures_defnoreturn.getVars,getVarModels:Blockly.Blocks.procedures_defnoreturn.getVarModels,renameVarById:Blockly.Blocks.procedures_defnoreturn.renameVarById,
updateVarName:Blockly.Blocks.procedures_defnoreturn.updateVarName,displayRenamedVar_:Blockly.Blocks.procedures_defnoreturn.displayRenamedVar_,customContextMenu:Blockly.Blocks.procedures_defnoreturn.customContextMenu,callType_:"procedures_callreturn"};
Blockly.Blocks.procedures_mutatorcontainer={init:function(){this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE);this.appendStatementInput("STACK");this.appendDummyInput("STATEMENT_INPUT").appendField(Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS).appendField(new Blockly.FieldCheckbox("TRUE"),"STATEMENTS");this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP);this.contextMenu=!1}};
Blockly.Blocks.procedures_mutatorarg={init:function(){var a=new Blockly.FieldTextInput("x",this.validator_);a.oldShowEditorFn_=a.showEditor_;a.showEditor_=function(){this.createdVariables_=[];this.oldShowEditorFn_()};this.appendDummyInput().appendField(Blockly.Msg.PROCEDURES_MUTATORARG_TITLE).appendField(a,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP);this.contextMenu=!1;a.onFinishEditing_=
this.deleteIntermediateVars_;a.createdVariables_=[];a.onFinishEditing_("x")},validator_:function(a){var b=Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);a=a.replace(/[\s\xa0]+/g," ").replace(/^ | $/g,"");if(!a)return null;var c=b.getVariable(a,"");c&&c.name!=a&&b.renameVarById(c.getId(),a);c||(c=b.createVariable(a,""))&&this.createdVariables_&&this.createdVariables_.push(c);return a},deleteIntermediateVars_:function(a){var b=Blockly.Mutator.findParentWs(this.sourceBlock_.workspace);if(b)for(var c=
0;c<this.createdVariables_.length;c++){var d=this.createdVariables_[c];d.name!=a&&b.deleteVariableById(d.getId())}}};
Blockly.Blocks.procedures_callnoreturn={init:function(){this.appendDummyInput("TOPROW").appendField(this.id,"NAME");this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL);this.arguments_=[];this.argumentVarModels_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:function(){return this.getFieldValue("NAME")},renameProcedure:function(a,b){Blockly.Names.equals(a,this.getProcedureCall())&&
(this.setFieldValue(b,"NAME"),this.setTooltip((this.outputConnection?Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP:Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP).replace("%1",b)))},setProcedureParameters_:function(a,b){var c=Blockly.Procedures.getDefinition(this.getProcedureCall(),this.workspace),d=c&&c.mutator&&c.mutator.isVisible();d||(this.quarkConnections_={},this.quarkIds_=null);if(b)if(goog.array.equals(this.arguments_,a))this.quarkIds_=b;else{if(b.length!=a.length)throw"Error: paramNames and paramIds must be the same length.";
this.setCollapsed(!1);this.quarkIds_||(this.quarkConnections_={},a.join("\n")==this.arguments_.join("\n")?this.quarkIds_=b:this.quarkIds_=[]);c=this.rendered;this.rendered=!1;for(var e=0;e<this.arguments_.length;e++){var f=this.getInput("ARG"+e);f&&(f=f.connection.targetConnection,this.quarkConnections_[this.quarkIds_[e]]=f,d&&f&&-1==b.indexOf(this.quarkIds_[e])&&(f.disconnect(),f.getSourceBlock().bumpNeighbours_()))}this.arguments_=[].concat(a);this.argumentVarModels_=[];for(e=0;e<this.arguments_.length;e++)d=
Blockly.Variables.getOrCreateVariablePackage(this.workspace,null,this.arguments_[e],""),this.argumentVarModels_.push(d);this.updateShape_();if(this.quarkIds_=b)for(e=0;e<this.arguments_.length;e++)d=this.quarkIds_[e],d in this.quarkConnections_&&(f=this.quarkConnections_[d],Blockly.Mutator.reconnect(f,this,"ARG"+e)||delete this.quarkConnections_[d]);(this.rendered=c)&&this.render()}},updateShape_:function(){for(var a=0;a<this.arguments_.length;a++){var b=this.getField("ARGNAME"+a);if(b){Blockly.Events.disable();
try{b.setValue(this.arguments_[a])}finally{Blockly.Events.enable()}}else b=new Blockly.FieldLabel(this.arguments_[a]),this.appendValueInput("ARG"+a).setAlign(Blockly.ALIGN_RIGHT).appendField(b,"ARGNAME"+a).init()}for(;this.getInput("ARG"+a);)this.removeInput("ARG"+a),a++;if(a=this.getInput("TOPROW"))this.arguments_.length?this.getField("WITH")||(a.appendField(Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS,"WITH"),a.init()):this.getField("WITH")&&a.removeField("WITH")},mutationToDom:function(){var a=document.createElement("mutation");
a.setAttribute("name",this.getProcedureCall());for(var b=0;b<this.arguments_.length;b++){var c=document.createElement("arg");c.setAttribute("name",this.arguments_[b]);a.appendChild(c)}return a},domToMutation:function(a){var b=a.getAttribute("name");this.renameProcedure(this.getProcedureCall(),b);b=[];for(var c=[],d=0,e;e=a.childNodes[d];d++)"arg"==e.nodeName.toLowerCase()&&(b.push(e.getAttribute("name")),c.push(e.getAttribute("paramId")));this.setProcedureParameters_(b,c)},getVarModels:function(){return this.argumentVarModels_},
onchange:function(a){if(this.workspace&&!this.workspace.isFlyout)if(a.type==Blockly.Events.BLOCK_CREATE&&-1!=a.ids.indexOf(this.id)){var b=this.getProcedureCall();b=Blockly.Procedures.getDefinition(b,this.workspace);!b||b.type==this.defType_&&JSON.stringify(b.arguments_)==JSON.stringify(this.arguments_)||(b=null);if(!b){Blockly.Events.setGroup(a.group);a=goog.dom.createDom("xml");b=goog.dom.createDom("block");b.setAttribute("type",this.defType_);var c=this.getRelativeToSurfaceXY(),d=c.y+2*Blockly.SNAP_RADIUS;
b.setAttribute("x",c.x+Blockly.SNAP_RADIUS*(this.RTL?-1:1));b.setAttribute("y",d);c=this.mutationToDom();b.appendChild(c);c=goog.dom.createDom("field");c.setAttribute("name","NAME");c.appendChild(document.createTextNode(this.getProcedureCall()));b.appendChild(c);a.appendChild(b);Blockly.Xml.domToWorkspace(a,this.workspace);Blockly.Events.setGroup(!1)}}else a.type==Blockly.Events.BLOCK_DELETE&&(b=this.getProcedureCall(),b=Blockly.Procedures.getDefinition(b,this.workspace),b||(Blockly.Events.setGroup(a.group),
this.dispose(!0,!1),Blockly.Events.setGroup(!1)))},customContextMenu:function(a){var b={enabled:!0};b.text=Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF;var c=this.getProcedureCall(),d=this.workspace;b.callback=function(){var a=Blockly.Procedures.getDefinition(c,d);a&&a.select()};a.push(b)},defType_:"procedures_defnoreturn"};
Blockly.Blocks.procedures_callreturn={init:function(){this.appendDummyInput("TOPROW").appendField("","NAME");this.setOutput(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setHelpUrl(Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL);this.arguments_=[];this.quarkConnections_={};this.quarkIds_=null},getProcedureCall:Blockly.Blocks.procedures_callnoreturn.getProcedureCall,renameProcedure:Blockly.Blocks.procedures_callnoreturn.renameProcedure,setProcedureParameters_:Blockly.Blocks.procedures_callnoreturn.setProcedureParameters_,
updateShape_:Blockly.Blocks.procedures_callnoreturn.updateShape_,mutationToDom:Blockly.Blocks.procedures_callnoreturn.mutationToDom,domToMutation:Blockly.Blocks.procedures_callnoreturn.domToMutation,getVarModels:Blockly.Blocks.procedures_callnoreturn.getVarModels,onchange:Blockly.Blocks.procedures_callnoreturn.onchange,customContextMenu:Blockly.Blocks.procedures_callnoreturn.customContextMenu,defType_:"procedures_defreturn"};
Blockly.Blocks.procedures_ifreturn={init:function(){this.appendValueInput("CONDITION").setCheck("Boolean").appendField(Blockly.Msg.CONTROLS_IF_MSG_IF);this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN);this.setInputsInline(!0);this.setPreviousStatement(!0);this.setNextStatement(!0);this.setColour(Blockly.Blocks.procedures.HUE);this.setTooltip(Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP);this.setHelpUrl(Blockly.Msg.PROCEDURES_IFRETURN_HELPURL);this.hasReturnValue_=!0},
mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("value",Number(this.hasReturnValue_));return a},domToMutation:function(a){this.hasReturnValue_=1==a.getAttribute("value");this.hasReturnValue_||(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN))},onchange:function(){if(this.workspace.isDragging&&!this.workspace.isDragging()){var a=!1,b=this;do{if(-1!=this.FUNCTION_TYPES.indexOf(b.type)){a=!0;break}b=b.getSurroundParent()}while(b);
a?("procedures_defnoreturn"==b.type&&this.hasReturnValue_?(this.removeInput("VALUE"),this.appendDummyInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!1):"procedures_defreturn"!=b.type||this.hasReturnValue_||(this.removeInput("VALUE"),this.appendValueInput("VALUE").appendField(Blockly.Msg.PROCEDURES_DEFRETURN_RETURN),this.hasReturnValue_=!0),this.setWarningText(null),this.isInFlyout||this.setDisabled(!1)):(this.setWarningText(Blockly.Msg.PROCEDURES_IFRETURN_WARNING),
this.isInFlyout||this.getInheritedDisabled()||this.setDisabled(!0))}},FUNCTION_TYPES:["procedures_defnoreturn","procedures_defreturn"]};Blockly.Blocks.texts={};Blockly.Constants.Text={};Blockly.Constants.Text.HUE=160;Blockly.Blocks.texts.HUE=Blockly.Constants.Text.HUE;
Blockly.defineBlocksWithJsonArray([{type:"text",message0:"%1",args0:[{type:"field_input",name:"TEXT",text:""}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_TEXT_HELPURL}",tooltip:"%{BKY_TEXT_TEXT_TOOLTIP}",extensions:["text_quotes","parent_tooltip_when_inline"]},{type:"text_join",message0:"",output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_JOIN_HELPURL}",tooltip:"%{BKY_TEXT_JOIN_TOOLTIP}",mutator:"text_join_mutator"},{type:"text_create_join_container",message0:"%{BKY_TEXT_CREATE_JOIN_TITLE_JOIN} %1 %2",
args0:[{type:"input_dummy"},{type:"input_statement",name:"STACK"}],colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_CREATE_JOIN_TOOLTIP}",enableContextMenu:!1},{type:"text_create_join_item",message0:"%{BKY_TEXT_CREATE_JOIN_ITEM_TITLE_ITEM}",previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",tooltip:"{%BKY_TEXT_CREATE_JOIN_ITEM_TOOLTIP}",enableContextMenu:!1},{type:"text_append",message0:"%{BKY_TEXT_APPEND_TITLE}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_TEXT_APPEND_VARIABLE}"},
{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:"%{BKY_TEXTS_HUE}",extensions:["text_append_tooltip"]},{type:"text_length",message0:"%{BKY_TEXT_LENGTH_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],output:"Number",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_LENGTH_TOOLTIP}",helpUrl:"%{BKY_TEXT_LENGTH_HELPURL}"},{type:"text_isEmpty",message0:"%{BKY_TEXT_ISEMPTY_TITLE}",args0:[{type:"input_value",name:"VALUE",check:["String","Array"]}],
output:"Boolean",colour:"%{BKY_TEXTS_HUE}",tooltip:"%{BKY_TEXT_ISEMPTY_TOOLTIP}",helpUrl:"%{BKY_TEXT_ISEMPTY_HELPURL}"},{type:"text_indexOf",message0:"%{BKY_TEXT_INDEXOF_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"END",options:[["%{BKY_TEXT_INDEXOF_OPERATOR_FIRST}","FIRST"],["%{BKY_TEXT_INDEXOF_OPERATOR_LAST}","LAST"]]},{type:"input_value",name:"FIND",check:"String"}],output:"Number",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_INDEXOF_HELPURL}",inputsInline:!0,
extensions:["text_indexOf_tooltip"]},{type:"text_charAt",message0:"%{BKY_TEXT_CHARAT_TITLE}",args0:[{type:"input_value",name:"VALUE",check:"String"},{type:"field_dropdown",name:"WHERE",options:[["%{BKY_TEXT_CHARAT_FROM_START}","FROM_START"],["%{BKY_TEXT_CHARAT_FROM_END}","FROM_END"],["%{BKY_TEXT_CHARAT_FIRST}","FIRST"],["%{BKY_TEXT_CHARAT_LAST}","LAST"],["%{BKY_TEXT_CHARAT_RANDOM}","RANDOM"]]}],output:"String",colour:"%{BKY_TEXTS_HUE}",helpUrl:"%{BKY_TEXT_CHARAT_HELPURL}",inputsInline:!0,mutator:"text_charAt_mutator"}]);
Blockly.Blocks.text_getSubstring={init:function(){this.WHERE_OPTIONS_1=[[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST,"FIRST"]];this.WHERE_OPTIONS_2=[[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START,"FROM_START"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END,"FROM_END"],[Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST,"LAST"]];this.setHelpUrl(Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);
this.appendValueInput("STRING").setCheck("String").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT);this.appendDummyInput("AT1");this.appendDummyInput("AT2");Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL);this.setInputsInline(!0);this.setOutput(!0,"String");this.updateAt_(1,!0);this.updateAt_(2,!0);this.setTooltip(Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP)},mutationToDom:function(){var a=document.createElement("mutation"),
b=this.getInput("AT1").type==Blockly.INPUT_VALUE;a.setAttribute("at1",b);b=this.getInput("AT2").type==Blockly.INPUT_VALUE;a.setAttribute("at2",b);return a},domToMutation:function(a){var b="true"==a.getAttribute("at1");a="true"==a.getAttribute("at2");this.updateAt_(1,b);this.updateAt_(2,a)},updateAt_:function(a,b){this.removeInput("AT"+a);this.removeInput("ORDINAL"+a,!0);b?(this.appendValueInput("AT"+a).setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL"+a).appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX)):
this.appendDummyInput("AT"+a);2==a&&Blockly.Msg.TEXT_GET_SUBSTRING_TAIL&&(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_GET_SUBSTRING_TAIL));var c=new Blockly.FieldDropdown(this["WHERE_OPTIONS_"+a],function(c){var d="FROM_START"==c||"FROM_END"==c;if(d!=b){var f=this.sourceBlock_;f.updateAt_(a,d);f.setFieldValue(c,"WHERE"+a);return null}});this.getInput("AT"+a).appendField(c,"WHERE"+a);1==a&&this.moveInputBefore("AT1","AT2")}};
Blockly.Blocks.text_changeCase={init:function(){var a=[[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE,"UPPERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE,"LOWERCASE"],[Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE,"TITLECASE"]];this.setHelpUrl(Blockly.Msg.TEXT_CHANGECASE_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"CASE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_CHANGECASE_TOOLTIP)}};
Blockly.Blocks.text_trim={init:function(){var a=[[Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH,"BOTH"],[Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT,"LEFT"],[Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT,"RIGHT"]];this.setHelpUrl(Blockly.Msg.TEXT_TRIM_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);this.appendValueInput("TEXT").setCheck("String").appendField(new Blockly.FieldDropdown(a),"MODE");this.setOutput(!0,"String");this.setTooltip(Blockly.Msg.TEXT_TRIM_TOOLTIP)}};
Blockly.Blocks.text_print={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_PRINT_TITLE,args0:[{type:"input_value",name:"TEXT"}],previousStatement:null,nextStatement:null,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_PRINT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_PRINT_HELPURL})}};
Blockly.Blocks.text_prompt_ext={init:function(){var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]];this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);var b=this;a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendValueInput("TEXT").appendField(a,"TYPE");this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},
updateType_:function(a){this.outputConnection.setCheck("NUMBER"==a?"Number":"String")},mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("type",this.getFieldValue("TYPE"));return a},domToMutation:function(a){this.updateType_(a.getAttribute("type"))}};
Blockly.Blocks.text_prompt={init:function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);var a=[[Blockly.Msg.TEXT_PROMPT_TYPE_TEXT,"TEXT"],[Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER,"NUMBER"]],b=this;this.setHelpUrl(Blockly.Msg.TEXT_PROMPT_HELPURL);this.setColour(Blockly.Blocks.texts.HUE);a=new Blockly.FieldDropdown(a,function(a){b.updateType_(a)});this.appendDummyInput().appendField(a,"TYPE").appendField(this.newQuote_(!0)).appendField(new Blockly.FieldTextInput(""),"TEXT").appendField(this.newQuote_(!1));
this.setOutput(!0,"String");this.setTooltip(function(){return"TEXT"==b.getFieldValue("TYPE")?Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT:Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER})},updateType_:Blockly.Blocks.text_prompt_ext.updateType_,mutationToDom:Blockly.Blocks.text_prompt_ext.mutationToDom,domToMutation:Blockly.Blocks.text_prompt_ext.domToMutation};
Blockly.Blocks.text_count={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_COUNT_MESSAGE0,args0:[{type:"input_value",name:"SUB",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"Number",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_COUNT_TOOLTIP,helpUrl:Blockly.Msg.TEXT_COUNT_HELPURL})}};
Blockly.Blocks.text_replace={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REPLACE_MESSAGE0,args0:[{type:"input_value",name:"FROM",check:"String"},{type:"input_value",name:"TO",check:"String"},{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REPLACE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REPLACE_HELPURL})}};
Blockly.Blocks.text_reverse={init:function(){this.jsonInit({message0:Blockly.Msg.TEXT_REVERSE_MESSAGE0,args0:[{type:"input_value",name:"TEXT",check:"String"}],output:"String",inputsInline:!0,colour:Blockly.Blocks.texts.HUE,tooltip:Blockly.Msg.TEXT_REVERSE_TOOLTIP,helpUrl:Blockly.Msg.TEXT_REVERSE_HELPURL})}};
Blockly.Constants.Text.QUOTE_IMAGE_MIXIN={QUOTE_IMAGE_LEFT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAn0lEQVQI1z3OMa5BURSF4f/cQhAKjUQhuQmFNwGJEUi0RKN5rU7FHKhpjEH3TEMtkdBSCY1EIv8r7nFX9e29V7EBAOvu7RPjwmWGH/VuF8CyN9/OAdvqIXYLvtRaNjx9mMTDyo+NjAN1HNcl9ZQ5oQMM3dgDUqDo1l8DzvwmtZN7mnD+PkmLa+4mhrxVA9fRowBWmVBhFy5gYEjKMfz9AylsaRRgGzvZAAAAAElFTkSuQmCC",QUOTE_IMAGE_RIGHT_DATAURI:"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAKCAQAAAAqJXdxAAAAqUlEQVQI1z3KvUpCcRiA8ef9E4JNHhI0aFEacm1o0BsI0Slx8wa8gLauoDnoBhq7DcfWhggONDmJJgqCPA7neJ7p934EOOKOnM8Q7PDElo/4x4lFb2DmuUjcUzS3URnGib9qaPNbuXvBO3sGPHJDRG6fGVdMSeWDP2q99FQdFrz26Gu5Tq7dFMzUvbXy8KXeAj57cOklgA+u1B5AoslLtGIHQMaCVnwDnADZIFIrXsoXrgAAAABJRU5ErkJggg==",
QUOTE_IMAGE_WIDTH:12,QUOTE_IMAGE_HEIGHT:12,quoteField_:function(a){for(var b=0,c;c=this.inputList[b];b++)for(var d=0,e;e=c.fieldRow[d];d++)if(a==e.name){c.insertFieldAt(d,this.newQuote_(!0));c.insertFieldAt(d+2,this.newQuote_(!1));return}console.warn('field named "'+a+'" not found in '+this.toDevString())},newQuote_:function(a){a=this.RTL?!a:a;return new Blockly.FieldImage(a?this.QUOTE_IMAGE_LEFT_DATAURI:this.QUOTE_IMAGE_RIGHT_DATAURI,this.QUOTE_IMAGE_WIDTH,this.QUOTE_IMAGE_HEIGHT,a?"\u201c":"\u201d")}};
Blockly.Constants.Text.TEXT_QUOTES_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.quoteField_("TEXT")};
Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("items",this.itemCount_);return a},domToMutation:function(a){this.itemCount_=parseInt(a.getAttribute("items"),10);this.updateShape_()},decompose:function(a){var b=a.newBlock("text_create_join_container");b.initSvg();for(var c=b.getInput("STACK").connection,d=0;d<this.itemCount_;d++){var e=a.newBlock("text_create_join_item");e.initSvg();c.connect(e.previousConnection);c=
e.nextConnection}return b},compose:function(a){var b=a.getInputTargetBlock("STACK");for(a=[];b;)a.push(b.valueConnection_),b=b.nextConnection&&b.nextConnection.targetBlock();for(b=0;b<this.itemCount_;b++){var c=this.getInput("ADD"+b).connection.targetConnection;c&&-1==a.indexOf(c)&&c.disconnect()}this.itemCount_=a.length;this.updateShape_();for(b=0;b<this.itemCount_;b++)Blockly.Mutator.reconnect(a[b],this,"ADD"+b)},saveConnections:function(a){a=a.getInputTargetBlock("STACK");for(var b=0;a;){var c=
this.getInput("ADD"+b);a.valueConnection_=c&&c.connection.targetConnection;b++;a=a.nextConnection&&a.nextConnection.targetBlock()}},updateShape_:function(){this.itemCount_&&this.getInput("EMPTY")?this.removeInput("EMPTY"):this.itemCount_||this.getInput("EMPTY")||this.appendDummyInput("EMPTY").appendField(this.newQuote_(!0)).appendField(this.newQuote_(!1));for(var a=0;a<this.itemCount_;a++)if(!this.getInput("ADD"+a)){var b=this.appendValueInput("ADD"+a);0==a&&b.appendField(Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH)}for(;this.getInput("ADD"+
a);)this.removeInput("ADD"+a),a++}};Blockly.Constants.Text.TEXT_JOIN_EXTENSION=function(){this.mixin(Blockly.Constants.Text.QUOTE_IMAGE_MIXIN);this.itemCount_=2;this.updateShape_();this.setMutator(new Blockly.Mutator(["text_create_join_item"]))};Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_APPEND_TOOLTIP?Blockly.Msg.TEXT_APPEND_TOOLTIP.replace("%1",a.getFieldValue("VAR")):""})};
Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION=function(){var a=this;this.setTooltip(function(){return Blockly.Msg.TEXT_INDEXOF_TOOLTIP.replace("%1",a.workspace.options.oneBasedIndex?"0":"-1")})};
Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN={mutationToDom:function(){var a=document.createElement("mutation");a.setAttribute("at",!!this.isAt_);return a},domToMutation:function(a){a="false"!=a.getAttribute("at");this.updateAt_(a)},updateAt_:function(a){this.removeInput("AT",!0);this.removeInput("ORDINAL",!0);a&&(this.appendValueInput("AT").setCheck("Number"),Blockly.Msg.ORDINAL_NUMBER_SUFFIX&&this.appendDummyInput("ORDINAL").appendField(Blockly.Msg.ORDINAL_NUMBER_SUFFIX));Blockly.Msg.TEXT_CHARAT_TAIL&&
(this.removeInput("TAIL",!0),this.appendDummyInput("TAIL").appendField(Blockly.Msg.TEXT_CHARAT_TAIL));this.isAt_=a}};
Blockly.Constants.Text.TEXT_CHARAT_EXTENSION=function(){this.getField("WHERE").setValidator(function(a){var b="FROM_START"==a||"FROM_END"==a;if(b!=this.isAt_){var d=this.sourceBlock_;d.updateAt_(b);d.setFieldValue(a,"WHERE");return null}});this.updateAt_(!0);var a=this;this.setTooltip(function(){var b=a.getFieldValue("WHERE"),c=Blockly.Msg.TEXT_CHARAT_TOOLTIP;("FROM_START"==b||"FROM_END"==b)&&(b="FROM_START"==b?Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP:Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP)&&
(c+=" "+b.replace("%1",a.workspace.options.oneBasedIndex?"#1":"#0"));return c})};Blockly.Extensions.register("text_indexOf_tooltip",Blockly.Constants.Text.TEXT_INDEXOF_TOOLTIP_EXTENSION);Blockly.Extensions.register("text_quotes",Blockly.Constants.Text.TEXT_QUOTES_EXTENSION);Blockly.Extensions.register("text_append_tooltip",Blockly.Constants.Text.TEXT_APPEND_TOOLTIP_EXTENSION);Blockly.Extensions.registerMutator("text_join_mutator",Blockly.Constants.Text.TEXT_JOIN_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_JOIN_EXTENSION);
Blockly.Extensions.registerMutator("text_charAt_mutator",Blockly.Constants.Text.TEXT_CHARAT_MUTATOR_MIXIN,Blockly.Constants.Text.TEXT_CHARAT_EXTENSION);Blockly.Blocks.variables={};Blockly.Constants.Variables={};Blockly.Constants.Variables.HUE=330;Blockly.Blocks.variables.HUE=Blockly.Constants.Variables.HUE;
Blockly.defineBlocksWithJsonArray([{type:"variables_get",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,colour:"%{BKY_VARIABLES_HUE}",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableSetterGetter"]},{type:"variables_set",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",name:"VALUE"}],previousStatement:null,
nextStatement:null,colour:"%{BKY_VARIABLES_HUE}",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableSetterGetter"]}]);
Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){if("variables_get"==this.type)var b="variables_set",c=Blockly.Msg.VARIABLES_GET_CREATE_SET;else b="variables_get",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getFieldValue("VAR");d.text=c.replace("%1",e);c=goog.dom.createDom("field",null,e);c.setAttribute("name","VAR");c=goog.dom.createDom("block",null,c);c.setAttribute("type",
b);d.callback=Blockly.ContextMenu.callbackFactory(this,c);a.push(d)}}};Blockly.Extensions.registerMixin("contextMenu_variableSetterGetter",Blockly.Constants.Variables.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);
Blockly.Constants.VariablesDynamic={};Blockly.Constants.VariablesDynamic.HUE=310;
Blockly.defineBlocksWithJsonArray([{type:"variables_get_dynamic",message0:"%1",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"}],output:null,colour:"%{BKY_VARIABLES_DYNAMIC_HUE}",helpUrl:"%{BKY_VARIABLES_GET_HELPURL}",tooltip:"%{BKY_VARIABLES_GET_TOOLTIP}",extensions:["contextMenu_variableDynamicSetterGetter"]},{type:"variables_set_dynamic",message0:"%{BKY_VARIABLES_SET}",args0:[{type:"field_variable",name:"VAR",variable:"%{BKY_VARIABLES_DEFAULT_NAME}"},{type:"input_value",
name:"VALUE"}],previousStatement:null,nextStatement:null,colour:"%{BKY_VARIABLES_DYNAMIC_HUE}",tooltip:"%{BKY_VARIABLES_SET_TOOLTIP}",helpUrl:"%{BKY_VARIABLES_SET_HELPURL}",extensions:["contextMenu_variableDynamicSetterGetter"]}]);
Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN={customContextMenu:function(a){if(!this.isInFlyout){if("variables_get_dynamic"==this.type){var b="variables_set_dynamic";var c=Blockly.Msg.VARIABLES_GET_CREATE_SET}else b="variables_get_dynamic",c=Blockly.Msg.VARIABLES_SET_CREATE_GET;var d={enabled:0<this.workspace.remainingCapacity()},e=this.getFieldValue("VAR");d.text=c.replace("%1",e);c=goog.dom.createDom("field",null,e);c.setAttribute("name","VAR");e=this.workspace.getVariable(e);
c.setAttribute("variabletype",e.type);e=goog.dom.createDom("block",null,c);e.setAttribute("type",b);d.callback=Blockly.ContextMenu.callbackFactory(this,e);a.push(d)}},onchange:function(){var a=this.getFieldValue("VAR");a=this.workspace.getVariableById(a);"variables_get_dynamic"==this.type?this.outputConnection.setCheck(a.type):this.getInput("VALUE").connection.setCheck(a.type)}};Blockly.Extensions.registerMixin("contextMenu_variableDynamicSetterGetter",Blockly.Constants.VariablesDynamic.CUSTOM_CONTEXT_MENU_VARIABLE_GETTER_SETTER_MIXIN);

View File

@ -0,0 +1,430 @@
// This file was automatically generated. Do not modify.
'use strict';
goog.provide('Blockly.Msg.en');
goog.require('Blockly.Msg');
/** @export */ Blockly.Msg.ADD_COMMENT = "Add Comment";
/** @export */ Blockly.Msg.CANNOT_DELETE_VARIABLE_PROCEDURE = "Can't delete the variable '%1' because it's part of the definition of the function '%2'";
/** @export */ Blockly.Msg.CHANGE_VALUE_TITLE = "Change value:";
/** @export */ Blockly.Msg.CLEAN_UP = "Clean up Blocks";
/** @export */ Blockly.Msg.COLLAPSE_ALL = "Collapse Blocks";
/** @export */ Blockly.Msg.COLLAPSE_BLOCK = "Collapse Block";
/** @export */ Blockly.Msg.COLOUR_BLEND_COLOUR1 = "colour 1";
/** @export */ Blockly.Msg.COLOUR_BLEND_COLOUR2 = "colour 2";
/** @export */ Blockly.Msg.COLOUR_BLEND_HELPURL = "http://meyerweb.com/eric/tools/color-blend/";
/** @export */ Blockly.Msg.COLOUR_BLEND_RATIO = "ratio";
/** @export */ Blockly.Msg.COLOUR_BLEND_TITLE = "blend";
/** @export */ Blockly.Msg.COLOUR_BLEND_TOOLTIP = "Blends two colours together with a given ratio (0.0 - 1.0).";
/** @export */ Blockly.Msg.COLOUR_PICKER_HELPURL = "https://en.wikipedia.org/wiki/Color";
/** @export */ Blockly.Msg.COLOUR_PICKER_TOOLTIP = "Choose a colour from the palette.";
/** @export */ Blockly.Msg.COLOUR_RANDOM_HELPURL = "http://randomcolour.com";
/** @export */ Blockly.Msg.COLOUR_RANDOM_TITLE = "random colour";
/** @export */ Blockly.Msg.COLOUR_RANDOM_TOOLTIP = "Choose a colour at random.";
/** @export */ Blockly.Msg.COLOUR_RGB_BLUE = "blue";
/** @export */ Blockly.Msg.COLOUR_RGB_GREEN = "green";
/** @export */ Blockly.Msg.COLOUR_RGB_HELPURL = "http://www.december.com/html/spec/colorper.html";
/** @export */ Blockly.Msg.COLOUR_RGB_RED = "red";
/** @export */ Blockly.Msg.COLOUR_RGB_TITLE = "colour with";
/** @export */ Blockly.Msg.COLOUR_RGB_TOOLTIP = "Create a colour with the specified amount of red, green, and blue. All values must be between 0 and 100.";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_HELPURL = "https://github.com/google/blockly/wiki/Loops#loop-termination-blocks";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK = "break out of loop";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE = "continue with next iteration of loop";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK = "Break out of the containing loop.";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE = "Skip the rest of this loop, and continue with the next iteration.";
/** @export */ Blockly.Msg.CONTROLS_FLOW_STATEMENTS_WARNING = "Warning: This block may only be used within a loop.";
/** @export */ Blockly.Msg.CONTROLS_FOREACH_HELPURL = "https://github.com/google/blockly/wiki/Loops#for-each";
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TITLE = "for each item %1 in list %2";
/** @export */ Blockly.Msg.CONTROLS_FOREACH_TOOLTIP = "For each item in a list, set the variable '%1' to the item, and then do some statements.";
/** @export */ Blockly.Msg.CONTROLS_FOR_HELPURL = "https://github.com/google/blockly/wiki/Loops#count-with";
/** @export */ Blockly.Msg.CONTROLS_FOR_TITLE = "count with %1 from %2 to %3 by %4";
/** @export */ Blockly.Msg.CONTROLS_FOR_TOOLTIP = "Have the variable '%1' take on the values from the start number to the end number, counting by the specified interval, and do the specified blocks.";
/** @export */ Blockly.Msg.CONTROLS_IF_ELSEIF_TOOLTIP = "Add a condition to the if block.";
/** @export */ Blockly.Msg.CONTROLS_IF_ELSE_TOOLTIP = "Add a final, catch-all condition to the if block.";
/** @export */ Blockly.Msg.CONTROLS_IF_HELPURL = "https://github.com/google/blockly/wiki/IfElse";
/** @export */ Blockly.Msg.CONTROLS_IF_IF_TOOLTIP = "Add, remove, or reorder sections to reconfigure this if block.";
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_ELSE = "else";
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_ELSEIF = "else if";
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_IF = "if";
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_1 = "If a value is true, then do some statements.";
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_2 = "If a value is true, then do the first block of statements. Otherwise, do the second block of statements.";
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_3 = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements.";
/** @export */ Blockly.Msg.CONTROLS_IF_TOOLTIP_4 = "If the first value is true, then do the first block of statements. Otherwise, if the second value is true, do the second block of statements. If none of the values are true, do the last block of statements.";
/** @export */ Blockly.Msg.CONTROLS_REPEAT_HELPURL = "https://en.wikipedia.org/wiki/For_loop";
/** @export */ Blockly.Msg.CONTROLS_REPEAT_INPUT_DO = "do";
/** @export */ Blockly.Msg.CONTROLS_REPEAT_TITLE = "repeat %1 times";
/** @export */ Blockly.Msg.CONTROLS_REPEAT_TOOLTIP = "Do some statements several times.";
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_HELPURL = "https://github.com/google/blockly/wiki/Loops#repeat";
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL = "repeat until";
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE = "repeat while";
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL = "While a value is false, then do some statements.";
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE = "While a value is true, then do some statements.";
/** @export */ Blockly.Msg.DELETE_ALL_BLOCKS = "Delete all %1 blocks?";
/** @export */ Blockly.Msg.DELETE_BLOCK = "Delete Block";
/** @export */ Blockly.Msg.DELETE_VARIABLE = "Delete the '%1' variable";
/** @export */ Blockly.Msg.DELETE_VARIABLE_CONFIRMATION = "Delete %1 uses of the '%2' variable?";
/** @export */ Blockly.Msg.DELETE_X_BLOCKS = "Delete %1 Blocks";
/** @export */ Blockly.Msg.DISABLE_BLOCK = "Disable Block";
/** @export */ Blockly.Msg.DUPLICATE_BLOCK = "Duplicate";
/** @export */ Blockly.Msg.ENABLE_BLOCK = "Enable Block";
/** @export */ Blockly.Msg.EXPAND_ALL = "Expand Blocks";
/** @export */ Blockly.Msg.EXPAND_BLOCK = "Expand Block";
/** @export */ Blockly.Msg.EXTERNAL_INPUTS = "External Inputs";
/** @export */ Blockly.Msg.HELP = "Help";
/** @export */ Blockly.Msg.INLINE_INPUTS = "Inline Inputs";
/** @export */ Blockly.Msg.IOS_CANCEL = "Cancel";
/** @export */ Blockly.Msg.IOS_ERROR = "Error";
/** @export */ Blockly.Msg.IOS_OK = "OK";
/** @export */ Blockly.Msg.IOS_PROCEDURES_ADD_INPUT = "+ Add Input";
/** @export */ Blockly.Msg.IOS_PROCEDURES_ALLOW_STATEMENTS = "Allow statements";
/** @export */ Blockly.Msg.IOS_PROCEDURES_DUPLICATE_INPUTS_ERROR = "This function has duplicate inputs.";
/** @export */ Blockly.Msg.IOS_PROCEDURES_INPUTS = "INPUTS";
/** @export */ Blockly.Msg.IOS_VARIABLES_ADD_BUTTON = "Add";
/** @export */ Blockly.Msg.IOS_VARIABLES_ADD_VARIABLE = "+ Add Variable";
/** @export */ Blockly.Msg.IOS_VARIABLES_DELETE_BUTTON = "Delete";
/** @export */ Blockly.Msg.IOS_VARIABLES_EMPTY_NAME_ERROR = "You can't use an empty variable name.";
/** @export */ Blockly.Msg.IOS_VARIABLES_RENAME_BUTTON = "Rename";
/** @export */ Blockly.Msg.IOS_VARIABLES_VARIABLE_NAME = "Variable name";
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-empty-list";
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_TITLE = "create empty list";
/** @export */ Blockly.Msg.LISTS_CREATE_EMPTY_TOOLTIP = "Returns a list, of length 0, containing no data records";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TITLE_ADD = "list";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_CONTAINER_TOOLTIP = "Add, remove, or reorder sections to reconfigure this list block.";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_INPUT_WITH = "create list with";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_ITEM_TOOLTIP = "Add an item to the list.";
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_TOOLTIP = "Create a list with any number of items.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FIRST = "first";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FROM_END = "# from end";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_FROM_START = "#";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_GET = "get";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_GET_REMOVE = "get and remove";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_LAST = "last";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_RANDOM = "random";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_REMOVE = "remove";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TAIL = "";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FIRST = "Returns the first item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_FROM = "Returns the item at the specified position in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_LAST = "Returns the last item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_RANDOM = "Returns a random item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FIRST = "Removes and returns the first item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_FROM = "Removes and returns the item at the specified position in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_LAST = "Removes and returns the last item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_GET_REMOVE_RANDOM = "Removes and returns a random item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FIRST = "Removes the first item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_FROM = "Removes the item at the specified position in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_LAST = "Removes the last item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_INDEX_TOOLTIP_REMOVE_RANDOM = "Removes a random item in a list.";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_END = "to # from end";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_FROM_START = "to #";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_END_LAST = "to last";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_HELPURL = "https://github.com/google/blockly/wiki/Lists#getting-a-sublist";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FIRST = "get sub-list from first";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_END = "get sub-list from # from end";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_START_FROM_START = "get sub-list from #";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_TAIL = "";
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_TOOLTIP = "Creates a copy of the specified portion of a list.";
/** @export */ Blockly.Msg.LISTS_INDEX_FROM_END_TOOLTIP = "%1 is the last item.";
/** @export */ Blockly.Msg.LISTS_INDEX_FROM_START_TOOLTIP = "%1 is the first item.";
/** @export */ Blockly.Msg.LISTS_INDEX_OF_FIRST = "find first occurrence of item";
/** @export */ Blockly.Msg.LISTS_INDEX_OF_HELPURL = "https://github.com/google/blockly/wiki/Lists#getting-items-from-a-list";
/** @export */ Blockly.Msg.LISTS_INDEX_OF_LAST = "find last occurrence of item";
/** @export */ Blockly.Msg.LISTS_INDEX_OF_TOOLTIP = "Returns the index of the first/last occurrence of the item in the list. Returns %1 if item is not found.";
/** @export */ Blockly.Msg.LISTS_INLIST = "in list";
/** @export */ Blockly.Msg.LISTS_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Lists#is-empty";
/** @export */ Blockly.Msg.LISTS_ISEMPTY_TITLE = "%1 is empty";
/** @export */ Blockly.Msg.LISTS_ISEMPTY_TOOLTIP = "Returns true if the list is empty.";
/** @export */ Blockly.Msg.LISTS_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Lists#length-of";
/** @export */ Blockly.Msg.LISTS_LENGTH_TITLE = "length of %1";
/** @export */ Blockly.Msg.LISTS_LENGTH_TOOLTIP = "Returns the length of a list.";
/** @export */ Blockly.Msg.LISTS_REPEAT_HELPURL = "https://github.com/google/blockly/wiki/Lists#create-list-with";
/** @export */ Blockly.Msg.LISTS_REPEAT_TITLE = "create list with item %1 repeated %2 times";
/** @export */ Blockly.Msg.LISTS_REPEAT_TOOLTIP = "Creates a list consisting of the given value repeated the specified number of times.";
/** @export */ Blockly.Msg.LISTS_REVERSE_HELPURL = "https://github.com/google/blockly/wiki/Lists#reversing-a-list";
/** @export */ Blockly.Msg.LISTS_REVERSE_MESSAGE0 = "reverse %1";
/** @export */ Blockly.Msg.LISTS_REVERSE_TOOLTIP = "Reverse a copy of a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_HELPURL = "https://github.com/google/blockly/wiki/Lists#in-list--set";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INPUT_TO = "as";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INSERT = "insert at";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_SET = "set";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FIRST = "Inserts the item at the start of a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_FROM = "Inserts the item at the specified position in a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_LAST = "Append the item to the end of a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_INSERT_RANDOM = "Inserts the item randomly in a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FIRST = "Sets the first item in a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_FROM = "Sets the item at the specified position in a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_LAST = "Sets the last item in a list.";
/** @export */ Blockly.Msg.LISTS_SET_INDEX_TOOLTIP_SET_RANDOM = "Sets a random item in a list.";
/** @export */ Blockly.Msg.LISTS_SORT_HELPURL = "https://github.com/google/blockly/wiki/Lists#sorting-a-list";
/** @export */ Blockly.Msg.LISTS_SORT_ORDER_ASCENDING = "ascending";
/** @export */ Blockly.Msg.LISTS_SORT_ORDER_DESCENDING = "descending";
/** @export */ Blockly.Msg.LISTS_SORT_TITLE = "sort %1 %2 %3";
/** @export */ Blockly.Msg.LISTS_SORT_TOOLTIP = "Sort a copy of a list.";
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_IGNORECASE = "alphabetic, ignore case";
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_NUMERIC = "numeric";
/** @export */ Blockly.Msg.LISTS_SORT_TYPE_TEXT = "alphabetic";
/** @export */ Blockly.Msg.LISTS_SPLIT_HELPURL = "https://github.com/google/blockly/wiki/Lists#splitting-strings-and-joining-lists";
/** @export */ Blockly.Msg.LISTS_SPLIT_LIST_FROM_TEXT = "make list from text";
/** @export */ Blockly.Msg.LISTS_SPLIT_TEXT_FROM_LIST = "make text from list";
/** @export */ Blockly.Msg.LISTS_SPLIT_TOOLTIP_JOIN = "Join a list of texts into one text, separated by a delimiter.";
/** @export */ Blockly.Msg.LISTS_SPLIT_TOOLTIP_SPLIT = "Split text into a list of texts, breaking at each delimiter.";
/** @export */ Blockly.Msg.LISTS_SPLIT_WITH_DELIMITER = "with delimiter";
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_FALSE = "false";
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_HELPURL = "https://github.com/google/blockly/wiki/Logic#values";
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_TOOLTIP = "Returns either true or false.";
/** @export */ Blockly.Msg.LOGIC_BOOLEAN_TRUE = "true";
/** @export */ Blockly.Msg.LOGIC_COMPARE_HELPURL = "https://en.wikipedia.org/wiki/Inequality_(mathematics)";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_EQ = "Return true if both inputs equal each other.";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GT = "Return true if the first input is greater than the second input.";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_GTE = "Return true if the first input is greater than or equal to the second input.";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LT = "Return true if the first input is smaller than the second input.";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_LTE = "Return true if the first input is smaller than or equal to the second input.";
/** @export */ Blockly.Msg.LOGIC_COMPARE_TOOLTIP_NEQ = "Return true if both inputs are not equal to each other.";
/** @export */ Blockly.Msg.LOGIC_NEGATE_HELPURL = "https://github.com/google/blockly/wiki/Logic#not";
/** @export */ Blockly.Msg.LOGIC_NEGATE_TITLE = "not %1";
/** @export */ Blockly.Msg.LOGIC_NEGATE_TOOLTIP = "Returns true if the input is false. Returns false if the input is true.";
/** @export */ Blockly.Msg.LOGIC_NULL = "null";
/** @export */ Blockly.Msg.LOGIC_NULL_HELPURL = "https://en.wikipedia.org/wiki/Nullable_type";
/** @export */ Blockly.Msg.LOGIC_NULL_TOOLTIP = "Returns null.";
/** @export */ Blockly.Msg.LOGIC_OPERATION_AND = "and";
/** @export */ Blockly.Msg.LOGIC_OPERATION_HELPURL = "https://github.com/google/blockly/wiki/Logic#logical-operations";
/** @export */ Blockly.Msg.LOGIC_OPERATION_OR = "or";
/** @export */ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_AND = "Return true if both inputs are true.";
/** @export */ Blockly.Msg.LOGIC_OPERATION_TOOLTIP_OR = "Return true if at least one of the inputs is true.";
/** @export */ Blockly.Msg.LOGIC_TERNARY_CONDITION = "test";
/** @export */ Blockly.Msg.LOGIC_TERNARY_HELPURL = "https://en.wikipedia.org/wiki/%3F:";
/** @export */ Blockly.Msg.LOGIC_TERNARY_IF_FALSE = "if false";
/** @export */ Blockly.Msg.LOGIC_TERNARY_IF_TRUE = "if true";
/** @export */ Blockly.Msg.LOGIC_TERNARY_TOOLTIP = "Check the condition in 'test'. If the condition is true, returns the 'if true' value; otherwise returns the 'if false' value.";
/** @export */ Blockly.Msg.MATH_ADDITION_SYMBOL = "+";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_HELPURL = "https://en.wikipedia.org/wiki/Arithmetic";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_ADD = "Return the sum of the two numbers.";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE = "Return the quotient of the two numbers.";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MINUS = "Return the difference of the two numbers.";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY = "Return the product of the two numbers.";
/** @export */ Blockly.Msg.MATH_ARITHMETIC_TOOLTIP_POWER = "Return the first number raised to the power of the second number.";
/** @export */ Blockly.Msg.MATH_CHANGE_HELPURL = "https://en.wikipedia.org/wiki/Programming_idiom#Incrementing_a_counter";
/** @export */ Blockly.Msg.MATH_CHANGE_TITLE = "change %1 by %2";
/** @export */ Blockly.Msg.MATH_CHANGE_TOOLTIP = "Add a number to variable '%1'.";
/** @export */ Blockly.Msg.MATH_CONSTANT_HELPURL = "https://en.wikipedia.org/wiki/Mathematical_constant";
/** @export */ Blockly.Msg.MATH_CONSTANT_TOOLTIP = "Return one of the common constants: π (3.141…), e (2.718…), φ (1.618…), sqrt(2) (1.414…), sqrt(½) (0.707…), or ∞ (infinity).";
/** @export */ Blockly.Msg.MATH_CONSTRAIN_HELPURL = "https://en.wikipedia.org/wiki/Clamping_(graphics)";
/** @export */ Blockly.Msg.MATH_CONSTRAIN_TITLE = "constrain %1 low %2 high %3";
/** @export */ Blockly.Msg.MATH_CONSTRAIN_TOOLTIP = "Constrain a number to be between the specified limits (inclusive).";
/** @export */ Blockly.Msg.MATH_DIVISION_SYMBOL = "÷";
/** @export */ Blockly.Msg.MATH_IS_DIVISIBLE_BY = "is divisible by";
/** @export */ Blockly.Msg.MATH_IS_EVEN = "is even";
/** @export */ Blockly.Msg.MATH_IS_NEGATIVE = "is negative";
/** @export */ Blockly.Msg.MATH_IS_ODD = "is odd";
/** @export */ Blockly.Msg.MATH_IS_POSITIVE = "is positive";
/** @export */ Blockly.Msg.MATH_IS_PRIME = "is prime";
/** @export */ Blockly.Msg.MATH_IS_TOOLTIP = "Check if a number is an even, odd, prime, whole, positive, negative, or if it is divisible by certain number. Returns true or false.";
/** @export */ Blockly.Msg.MATH_IS_WHOLE = "is whole";
/** @export */ Blockly.Msg.MATH_MODULO_HELPURL = "https://en.wikipedia.org/wiki/Modulo_operation";
/** @export */ Blockly.Msg.MATH_MODULO_TITLE = "remainder of %1 ÷ %2";
/** @export */ Blockly.Msg.MATH_MODULO_TOOLTIP = "Return the remainder from dividing the two numbers.";
/** @export */ Blockly.Msg.MATH_MULTIPLICATION_SYMBOL = "×";
/** @export */ Blockly.Msg.MATH_NUMBER_HELPURL = "https://en.wikipedia.org/wiki/Number";
/** @export */ Blockly.Msg.MATH_NUMBER_TOOLTIP = "A number.";
/** @export */ Blockly.Msg.MATH_ONLIST_HELPURL = "";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_AVERAGE = "average of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MAX = "max of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MEDIAN = "median of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MIN = "min of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = "modes of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_RANDOM = "random item of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_STD_DEV = "standard deviation of list";
/** @export */ Blockly.Msg.MATH_ONLIST_OPERATOR_SUM = "sum of list";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_AVERAGE = "Return the average (arithmetic mean) of the numeric values in the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MAX = "Return the largest number in the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MEDIAN = "Return the median number in the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MIN = "Return the smallest number in the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_MODE = "Return a list of the most common item(s) in the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_RANDOM = "Return a random element from the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_STD_DEV = "Return the standard deviation of the list.";
/** @export */ Blockly.Msg.MATH_ONLIST_TOOLTIP_SUM = "Return the sum of all the numbers in the list.";
/** @export */ Blockly.Msg.MATH_POWER_SYMBOL = "^";
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_HELPURL = "https://en.wikipedia.org/wiki/Random_number_generation";
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM = "random fraction";
/** @export */ Blockly.Msg.MATH_RANDOM_FLOAT_TOOLTIP = "Return a random fraction between 0.0 (inclusive) and 1.0 (exclusive).";
/** @export */ Blockly.Msg.MATH_RANDOM_INT_HELPURL = "https://en.wikipedia.org/wiki/Random_number_generation";
/** @export */ Blockly.Msg.MATH_RANDOM_INT_TITLE = "random integer from %1 to %2";
/** @export */ Blockly.Msg.MATH_RANDOM_INT_TOOLTIP = "Return a random integer between the two specified limits, inclusive.";
/** @export */ Blockly.Msg.MATH_ROUND_HELPURL = "https://en.wikipedia.org/wiki/Rounding";
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUND = "round";
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDDOWN = "round down";
/** @export */ Blockly.Msg.MATH_ROUND_OPERATOR_ROUNDUP = "round up";
/** @export */ Blockly.Msg.MATH_ROUND_TOOLTIP = "Round a number up or down.";
/** @export */ Blockly.Msg.MATH_SINGLE_HELPURL = "https://en.wikipedia.org/wiki/Square_root";
/** @export */ Blockly.Msg.MATH_SINGLE_OP_ABSOLUTE = "absolute";
/** @export */ Blockly.Msg.MATH_SINGLE_OP_ROOT = "square root";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_ABS = "Return the absolute value of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_EXP = "Return e to the power of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_LN = "Return the natural logarithm of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_LOG10 = "Return the base 10 logarithm of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_NEG = "Return the negation of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_POW10 = "Return 10 to the power of a number.";
/** @export */ Blockly.Msg.MATH_SINGLE_TOOLTIP_ROOT = "Return the square root of a number.";
/** @export */ Blockly.Msg.MATH_SUBTRACTION_SYMBOL = "-";
/** @export */ Blockly.Msg.MATH_TRIG_ACOS = "acos";
/** @export */ Blockly.Msg.MATH_TRIG_ASIN = "asin";
/** @export */ Blockly.Msg.MATH_TRIG_ATAN = "atan";
/** @export */ Blockly.Msg.MATH_TRIG_COS = "cos";
/** @export */ Blockly.Msg.MATH_TRIG_HELPURL = "https://en.wikipedia.org/wiki/Trigonometric_functions";
/** @export */ Blockly.Msg.MATH_TRIG_SIN = "sin";
/** @export */ Blockly.Msg.MATH_TRIG_TAN = "tan";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ACOS = "Return the arccosine of a number.";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ASIN = "Return the arcsine of a number.";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_ATAN = "Return the arctangent of a number.";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_COS = "Return the cosine of a degree (not radian).";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_SIN = "Return the sine of a degree (not radian).";
/** @export */ Blockly.Msg.MATH_TRIG_TOOLTIP_TAN = "Return the tangent of a degree (not radian).";
/** @export */ Blockly.Msg.NEW_COLOUR_VARIABLE = "Create colour variable...";
/** @export */ Blockly.Msg.NEW_NUMBER_VARIABLE = "Create number variable...";
/** @export */ Blockly.Msg.NEW_STRING_VARIABLE = "Create string variable...";
/** @export */ Blockly.Msg.NEW_VARIABLE = "Create variable...";
/** @export */ Blockly.Msg.NEW_VARIABLE_TITLE = "New variable name:";
/** @export */ Blockly.Msg.NEW_VARIABLE_TYPE_TITLE = "New variable type:";
/** @export */ Blockly.Msg.ORDINAL_NUMBER_SUFFIX = "";
/** @export */ Blockly.Msg.PROCEDURES_ALLOW_STATEMENTS = "allow statements";
/** @export */ Blockly.Msg.PROCEDURES_BEFORE_PARAMS = "with:";
/** @export */ Blockly.Msg.PROCEDURES_CALLNORETURN_HELPURL = "https://en.wikipedia.org/wiki/Subroutine";
/** @export */ Blockly.Msg.PROCEDURES_CALLNORETURN_TOOLTIP = "Run the user-defined function '%1'.";
/** @export */ Blockly.Msg.PROCEDURES_CALLRETURN_HELPURL = "https://en.wikipedia.org/wiki/Subroutine";
/** @export */ Blockly.Msg.PROCEDURES_CALLRETURN_TOOLTIP = "Run the user-defined function '%1' and use its output.";
/** @export */ Blockly.Msg.PROCEDURES_CALL_BEFORE_PARAMS = "with:";
/** @export */ Blockly.Msg.PROCEDURES_CREATE_DO = "Create '%1'";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT = "Describe this function...";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_DO = "";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_HELPURL = "https://en.wikipedia.org/wiki/Subroutine";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE = "do something";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE = "to";
/** @export */ Blockly.Msg.PROCEDURES_DEFNORETURN_TOOLTIP = "Creates a function with no output.";
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_HELPURL = "https://en.wikipedia.org/wiki/Subroutine";
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_RETURN = "return";
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_TOOLTIP = "Creates a function with an output.";
/** @export */ Blockly.Msg.PROCEDURES_DEF_DUPLICATE_WARNING = "Warning: This function has duplicate parameters.";
/** @export */ Blockly.Msg.PROCEDURES_HIGHLIGHT_DEF = "Highlight function definition";
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_HELPURL = "http://c2.com/cgi/wiki?GuardClause";
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_TOOLTIP = "If a value is true, then return a second value.";
/** @export */ Blockly.Msg.PROCEDURES_IFRETURN_WARNING = "Warning: This block may be used only within a function definition.";
/** @export */ Blockly.Msg.PROCEDURES_MUTATORARG_TITLE = "input name:";
/** @export */ Blockly.Msg.PROCEDURES_MUTATORARG_TOOLTIP = "Add an input to the function.";
/** @export */ Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TITLE = "inputs";
/** @export */ Blockly.Msg.PROCEDURES_MUTATORCONTAINER_TOOLTIP = "Add, remove, or reorder inputs to this function.";
/** @export */ Blockly.Msg.REDO = "Redo";
/** @export */ Blockly.Msg.REMOVE_COMMENT = "Remove Comment";
/** @export */ Blockly.Msg.RENAME_VARIABLE = "Rename variable...";
/** @export */ Blockly.Msg.RENAME_VARIABLE_TITLE = "Rename all '%1' variables to:";
/** @export */ Blockly.Msg.TEXT_APPEND_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification";
/** @export */ Blockly.Msg.TEXT_APPEND_TITLE = "to %1 append text %2";
/** @export */ Blockly.Msg.TEXT_APPEND_TOOLTIP = "Append some text to variable '%1'.";
/** @export */ Blockly.Msg.TEXT_CHANGECASE_HELPURL = "https://github.com/google/blockly/wiki/Text#adjusting-text-case";
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_LOWERCASE = "to lower case";
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_TITLECASE = "to Title Case";
/** @export */ Blockly.Msg.TEXT_CHANGECASE_OPERATOR_UPPERCASE = "to UPPER CASE";
/** @export */ Blockly.Msg.TEXT_CHANGECASE_TOOLTIP = "Return a copy of the text in a different case.";
/** @export */ Blockly.Msg.TEXT_CHARAT_FIRST = "get first letter";
/** @export */ Blockly.Msg.TEXT_CHARAT_FROM_END = "get letter # from end";
/** @export */ Blockly.Msg.TEXT_CHARAT_FROM_START = "get letter #";
/** @export */ Blockly.Msg.TEXT_CHARAT_HELPURL = "https://github.com/google/blockly/wiki/Text#extracting-text";
/** @export */ Blockly.Msg.TEXT_CHARAT_LAST = "get last letter";
/** @export */ Blockly.Msg.TEXT_CHARAT_RANDOM = "get random letter";
/** @export */ Blockly.Msg.TEXT_CHARAT_TAIL = "";
/** @export */ Blockly.Msg.TEXT_CHARAT_TITLE = "in text %1 %2";
/** @export */ Blockly.Msg.TEXT_CHARAT_TOOLTIP = "Returns the letter at the specified position.";
/** @export */ Blockly.Msg.TEXT_COUNT_HELPURL = "https://github.com/google/blockly/wiki/Text#counting-substrings";
/** @export */ Blockly.Msg.TEXT_COUNT_MESSAGE0 = "count %1 in %2";
/** @export */ Blockly.Msg.TEXT_COUNT_TOOLTIP = "Count how many times some text occurs within some other text.";
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TOOLTIP = "Add an item to the text.";
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_TITLE_JOIN = "join";
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_TOOLTIP = "Add, remove, or reorder sections to reconfigure this text block.";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_END = "to letter # from end";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_FROM_START = "to letter #";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_END_LAST = "to last letter";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_HELPURL = "https://github.com/google/blockly/wiki/Text#extracting-a-region-of-text";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_INPUT_IN_TEXT = "in text";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FIRST = "get substring from first letter";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_END = "get substring from letter # from end";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_START_FROM_START = "get substring from letter #";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_TAIL = "";
/** @export */ Blockly.Msg.TEXT_GET_SUBSTRING_TOOLTIP = "Returns a specified portion of the text.";
/** @export */ Blockly.Msg.TEXT_INDEXOF_HELPURL = "https://github.com/google/blockly/wiki/Text#finding-text";
/** @export */ Blockly.Msg.TEXT_INDEXOF_OPERATOR_FIRST = "find first occurrence of text";
/** @export */ Blockly.Msg.TEXT_INDEXOF_OPERATOR_LAST = "find last occurrence of text";
/** @export */ Blockly.Msg.TEXT_INDEXOF_TITLE = "in text %1 %2 %3";
/** @export */ Blockly.Msg.TEXT_INDEXOF_TOOLTIP = "Returns the index of the first/last occurrence of the first text in the second text. Returns %1 if text is not found.";
/** @export */ Blockly.Msg.TEXT_ISEMPTY_HELPURL = "https://github.com/google/blockly/wiki/Text#checking-for-empty-text";
/** @export */ Blockly.Msg.TEXT_ISEMPTY_TITLE = "%1 is empty";
/** @export */ Blockly.Msg.TEXT_ISEMPTY_TOOLTIP = "Returns true if the provided text is empty.";
/** @export */ Blockly.Msg.TEXT_JOIN_HELPURL = "https://github.com/google/blockly/wiki/Text#text-creation";
/** @export */ Blockly.Msg.TEXT_JOIN_TITLE_CREATEWITH = "create text with";
/** @export */ Blockly.Msg.TEXT_JOIN_TOOLTIP = "Create a piece of text by joining together any number of items.";
/** @export */ Blockly.Msg.TEXT_LENGTH_HELPURL = "https://github.com/google/blockly/wiki/Text#text-modification";
/** @export */ Blockly.Msg.TEXT_LENGTH_TITLE = "length of %1";
/** @export */ Blockly.Msg.TEXT_LENGTH_TOOLTIP = "Returns the number of letters (including spaces) in the provided text.";
/** @export */ Blockly.Msg.TEXT_PRINT_HELPURL = "https://github.com/google/blockly/wiki/Text#printing-text";
/** @export */ Blockly.Msg.TEXT_PRINT_TITLE = "print %1";
/** @export */ Blockly.Msg.TEXT_PRINT_TOOLTIP = "Print the specified text, number or other value.";
/** @export */ Blockly.Msg.TEXT_PROMPT_HELPURL = "https://github.com/google/blockly/wiki/Text#getting-input-from-the-user";
/** @export */ Blockly.Msg.TEXT_PROMPT_TOOLTIP_NUMBER = "Prompt for user for a number.";
/** @export */ Blockly.Msg.TEXT_PROMPT_TOOLTIP_TEXT = "Prompt for user for some text.";
/** @export */ Blockly.Msg.TEXT_PROMPT_TYPE_NUMBER = "prompt for number with message";
/** @export */ Blockly.Msg.TEXT_PROMPT_TYPE_TEXT = "prompt for text with message";
/** @export */ Blockly.Msg.TEXT_REPLACE_HELPURL = "https://github.com/google/blockly/wiki/Text#replacing-substrings";
/** @export */ Blockly.Msg.TEXT_REPLACE_MESSAGE0 = "replace %1 with %2 in %3";
/** @export */ Blockly.Msg.TEXT_REPLACE_TOOLTIP = "Replace all occurances of some text within some other text.";
/** @export */ Blockly.Msg.TEXT_REVERSE_HELPURL = "https://github.com/google/blockly/wiki/Text#reversing-text";
/** @export */ Blockly.Msg.TEXT_REVERSE_MESSAGE0 = "reverse %1";
/** @export */ Blockly.Msg.TEXT_REVERSE_TOOLTIP = "Reverses the order of the characters in the text.";
/** @export */ Blockly.Msg.TEXT_TEXT_HELPURL = "https://en.wikipedia.org/wiki/String_(computer_science)";
/** @export */ Blockly.Msg.TEXT_TEXT_TOOLTIP = "A letter, word, or line of text.";
/** @export */ Blockly.Msg.TEXT_TRIM_HELPURL = "https://github.com/google/blockly/wiki/Text#trimming-removing-spaces";
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_BOTH = "trim spaces from both sides of";
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_LEFT = "trim spaces from left side of";
/** @export */ Blockly.Msg.TEXT_TRIM_OPERATOR_RIGHT = "trim spaces from right side of";
/** @export */ Blockly.Msg.TEXT_TRIM_TOOLTIP = "Return a copy of the text with spaces removed from one or both ends.";
/** @export */ Blockly.Msg.TODAY = "Today";
/** @export */ Blockly.Msg.UNDO = "Undo";
/** @export */ Blockly.Msg.VARIABLES_DEFAULT_NAME = "item";
/** @export */ Blockly.Msg.VARIABLES_GET_CREATE_SET = "Create 'set %1'";
/** @export */ Blockly.Msg.VARIABLES_GET_HELPURL = "https://github.com/google/blockly/wiki/Variables#get";
/** @export */ Blockly.Msg.VARIABLES_GET_TOOLTIP = "Returns the value of this variable.";
/** @export */ Blockly.Msg.VARIABLES_SET = "set %1 to %2";
/** @export */ Blockly.Msg.VARIABLES_SET_CREATE_GET = "Create 'get %1'";
/** @export */ Blockly.Msg.VARIABLES_SET_HELPURL = "https://github.com/google/blockly/wiki/Variables#set";
/** @export */ Blockly.Msg.VARIABLES_SET_TOOLTIP = "Sets this variable to be equal to the input.";
/** @export */ Blockly.Msg.VARIABLE_ALREADY_EXISTS = "A variable named '%1' already exists.";
/** @export */ Blockly.Msg.VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE = "A variable named '%1' already exists for another type: '%2'.";
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_TITLE = Blockly.Msg.PROCEDURES_DEFNORETURN_TITLE;
/** @export */ Blockly.Msg.CONTROLS_IF_IF_TITLE_IF = Blockly.Msg.CONTROLS_IF_MSG_IF;
/** @export */ Blockly.Msg.CONTROLS_WHILEUNTIL_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
/** @export */ Blockly.Msg.CONTROLS_IF_MSG_THEN = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
/** @export */ Blockly.Msg.CONTROLS_IF_ELSE_TITLE_ELSE = Blockly.Msg.CONTROLS_IF_MSG_ELSE;
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_PROCEDURE = Blockly.Msg.PROCEDURES_DEFNORETURN_PROCEDURE;
/** @export */ Blockly.Msg.LISTS_GET_SUBLIST_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
/** @export */ Blockly.Msg.LISTS_GET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
/** @export */ Blockly.Msg.MATH_CHANGE_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_DO = Blockly.Msg.PROCEDURES_DEFNORETURN_DO;
/** @export */ Blockly.Msg.CONTROLS_IF_ELSEIF_TITLE_ELSEIF = Blockly.Msg.CONTROLS_IF_MSG_ELSEIF;
/** @export */ Blockly.Msg.LISTS_GET_INDEX_HELPURL = Blockly.Msg.LISTS_INDEX_OF_HELPURL;
/** @export */ Blockly.Msg.CONTROLS_FOREACH_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
/** @export */ Blockly.Msg.LISTS_SET_INDEX_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
/** @export */ Blockly.Msg.CONTROLS_FOR_INPUT_DO = Blockly.Msg.CONTROLS_REPEAT_INPUT_DO;
/** @export */ Blockly.Msg.LISTS_CREATE_WITH_ITEM_TITLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
/** @export */ Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME;
/** @export */ Blockly.Msg.TEXT_CREATE_JOIN_ITEM_TITLE_ITEM = Blockly.Msg.VARIABLES_DEFAULT_NAME;
/** @export */ Blockly.Msg.LISTS_INDEX_OF_INPUT_IN_LIST = Blockly.Msg.LISTS_INLIST;
/** @export */ Blockly.Msg.PROCEDURES_DEFRETURN_COMMENT = Blockly.Msg.PROCEDURES_DEFNORETURN_COMMENT;
/** @export */ Blockly.Msg.MATH_HUE = "230";
/** @export */ Blockly.Msg.LOOPS_HUE = "120";
/** @export */ Blockly.Msg.LISTS_HUE = "260";
/** @export */ Blockly.Msg.LOGIC_HUE = "210";
/** @export */ Blockly.Msg.VARIABLES_HUE = "330";
/** @export */ Blockly.Msg.TEXTS_HUE = "160";
/** @export */ Blockly.Msg.PROCEDURES_HUE = "290";
/** @export */ Blockly.Msg.COLOUR_HUE = "20";
/** @export */ Blockly.Msg.VARIABLES_DYNAMIC_HUE = "310";

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,100 @@
class CodeBlock extends this.OS.GUI.BaseApplication
constructor: (args) ->
super "CodeBlock", args
main: () ->
me = @
@scheme.set "apptitle", "CodeBlock"
@btnact = @find "btn-action"
@container = @find "ws"
#file = "#{@path()}/toolbox.xml".asFileHandler()
#console.log file
#file.read (d) ->
# return me.error "Cannot load the toolbox" if d.error
#console.log d
#toolbox = $.parseHTML d
#me.scheme.append toolbox
me.workspace = Blockly.inject me.container,
{
grid:
spacing: 25
length: 3
colour: '#ccc'
snap: true
zoom:
controls: true
wheel: true
toolbox: @find "blockly_toolbox"
}
#if(Blockly.RpiControl)
# this.workspace.registerToolboxCategoryCallback('EXTRAS', function(workspace)
# {
# var xmlList = [];
# for (var i = 0; i < Blockly.RpiControl.length; i++) {
# var el = Blockly.RpiControl[i];
# if (Blockly.Blocks[el]) {
# var blockText = '<xml><block type="'+el+'"></block></xml>';
# var block = Blockly.Xml.textToDom(blockText).firstChild;
# xmlList.push(block);
# }
# }
# return xmlList;
#});
@blen = 1024
#@btnact.set "onbtclick", (e) ->
#me.openSession()
# code = Blockly.JavaScript.workspaceToCode me.workspace
# console.log code
@on "resize", () ->
Blockly.svgResize me.workspace
@bindKey "ALT-N", () -> me.actionFile "#{me.name}-New"
@bindKey "ALT-O", () -> me.actionFile "#{me.name}-Open"
@bindKey "CTRL-S", () -> me.actionFile "#{me.name}-Save"
@bindKey "ALT-W", () -> me.actionFile "#{me.name}-Saveas"
menu: () ->
me = @
menu = [{
text: "File",
child: [
{ text: __("New"), dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" }
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
}]
menu
actionFile: (n) ->
console.log n
openSession: () ->
me = @
proto = if window.location.protocol is "https:" then "wss://" else "ws://"
@socket = new WebSocket proto + @_api.HOST + "/ws/filestream.lua"
@socket.binaryType = "arraybuffer"
@socket.onopen = () ->
console.log "socket open"
enc = new TextEncoder "utf-8"
me.socket.send enc.encode me.blen + "os://packages/packages.json"
@socket.onmessage = (e) ->
console.log e.data
console.log new TextDecoder("utf-8").decode new Uint8Array e.data
me.socket.close() if e.data.byteLength < me.blen
@socket.onclose = () ->
me.socket = null
console.log "socket closed"
cleanup: (e) ->
@socket.close() if @socket
CodeBlock.singleton = true
this.OS.register "CodeBlock", CodeBlock

View File

@ -0,0 +1,13 @@
{
"app":"CodeBlock",
"name":"CodeBlock",
"description":"Programming using interlocking blocks",
"info":{
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"version":"0.1a",
"category":"Programming",
"iconclass":"fa fa-puzzle-piece",
"mimes":["none"]
}

View File

@ -0,0 +1,302 @@
<afx-app-window apptitle="CodeBlock" width="600" height="400">
<afx-vbox data-id = "mybox">
<!--afx-button data-height="20" text= "Action" data-id = "btn-action" ></afx-button-->
<div data-id="ws"></div>
<xml id="blockly_toolbox" data-height="0" data-id="blockly_toolbox" style="display: none">
<category name="Logic" colour="210">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_negate"></block>
<block type="logic_boolean"></block>
<block type="logic_null"></block>
<block type="logic_ternary"></block>
</category>
<category name="Loops" colour="120">
<block type="controls_repeat_ext">
<value name="TIMES">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
<block type="controls_whileUntil"></block>
<block type="controls_for">
<value name="FROM">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="TO">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
<value name="BY">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
<block type="controls_forEach"></block>
<block type="controls_flow_statements"></block>
</category>
<category name="Math" colour="230">
<block type="math_number"></block>
<block type="math_arithmetic">
<value name="A">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="B">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
<block type="math_single">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">9</field>
</shadow>
</value>
</block>
<block type="math_trig">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">45</field>
</shadow>
</value>
</block>
<block type="math_constant"></block>
<block type="math_number_property">
<value name="NUMBER_TO_CHECK">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="math_round">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">3.1</field>
</shadow>
</value>
</block>
<block type="math_on_list"></block>
<block type="math_modulo">
<value name="DIVIDEND">
<shadow type="math_number">
<field name="NUM">64</field>
</shadow>
</value>
<value name="DIVISOR">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
<block type="math_constrain">
<value name="VALUE">
<shadow type="math_number">
<field name="NUM">50</field>
</shadow>
</value>
<value name="LOW">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="HIGH">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>
<block type="math_random_int">
<value name="FROM">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="TO">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>
<block type="math_random_float"></block>
</category>
<category name="Text" colour="160">
<block type="text"></block>
<block type="text_join"></block>
<block type="text_append">
<value name="TEXT">
<shadow type="text"></shadow>
</value>
</block>
<block type="text_length">
<value name="VALUE">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_isEmpty">
<value name="VALUE">
<shadow type="text">
<field name="TEXT"></field>
</shadow>
</value>
</block>
<block type="text_indexOf">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
<value name="FIND">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_charAt">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
</block>
<block type="text_getSubstring">
<value name="STRING">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
</block>
<block type="text_changeCase">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_trim">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_print">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_prompt_ext">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
</category>
<category name="List" colour="260">
<block type="lists_create_with">
<mutation items="0"></mutation>
</block>
<block type="lists_create_with"></block>
<block type="lists_repeat">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">5</field>
</shadow>
</value>
</block>
<block type="lists_length"></block>
<block type="lists_isEmpty"></block>
<block type="lists_indexOf">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_getIndex">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_setIndex">
<value name="LIST">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_getSublist">
<value name="LIST">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_split">
<value name="DELIM">
<shadow type="text">
<field name="TEXT">,</field>
</shadow>
</value>
</block>
<block type="lists_sort"></block>
</category>
<category name="Colour" colour="20">
<block type="colour_picker"></block>
<block type="colour_random"></block>
<block type="colour_rgb">
<value name="RED">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="GREEN">
<shadow type="math_number">
<field name="NUM">50</field>
</shadow>
</value>
<value name="BLUE">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="colour_blend">
<value name="COLOUR1">
<shadow type="colour_picker">
<field name="COLOUR">#ff0000</field>
</shadow>
</value>
<value name="COLOUR2">
<shadow type="colour_picker">
<field name="COLOUR">#3333ff</field>
</shadow>
</value>
<value name="RATIO">
<shadow type="math_number">
<field name="NUM">0.5</field>
</shadow>
</value>
</block>
</category>
<sep></sep>
<category name="Variables" colour="330" custom="VARIABLE"></category>
<category name="Functions" colour="290" custom="PROCEDURE"></category>
</xml>
</afx-vbox>
</afx-app-window>

View File

@ -62,8 +62,8 @@ class PushNotification extends this.OS.GUI.BaseService
icon: o.data.icon,
iconclass: o.data.iconclass,
closable: true }
console.log o.data.s
console.log o.data.e
#console.log o.data.s
#console.log o.data.e
@mlist.unshift d, true
@notifeed d
@ -97,7 +97,7 @@ class PushNotification extends this.OS.GUI.BaseService
PushNotification.scheme = """
<afx-dummy>
<afx-overlay data-id = "notifyzone" width = "250">
<afx-button text = "Clear all" data-id = "btclear"></afx-button>
<afx-button text = "__(Clear all)" data-id = "btclear"></afx-button>
<afx-list-view data-id="notifylist"></afx-list-view>
</afx-overlay>
<afx-overlay data-id = "feedzone" width = "250">

View File

@ -7,17 +7,17 @@ class UserService extends this.OS.GUI.BaseService
me = @
@child = [
{
text: "About", dataid: "user-about",
text: "__(About)", dataid: "user-about",
iconclass: "fa fa-user-circle-o"
},
{
text: "Logout", dataid: "sys-logout",
text: "__(Logout)", dataid: "sys-logout",
iconclass: "fa fa-user-times"
}
]
@onmenuselect = (d) ->
return window.OS.exit() if d.item.data.dataid is "sys-logout"
me.notify "This feature is not implemented yet"
me.notify __("This feature is not implemented yet")
awake: (e) ->
cleanup: (evt) ->

View File

@ -10,6 +10,6 @@
},
"version":"0.1a",
"category":"System",
"iconclass":"fa fa-user-circle-o",
"icon": "icon.png",
"mimes":["none"]
}

View File

@ -2,12 +2,12 @@
<afx-hbox>
<afx-switch enable= true data-width="50"></afx-switch>
<afx-vbox>
<afx-tab-container data-height = "50" data-id="mytabs" closable = true></afx-tab-container>
<afx-tab-bar data-height = "50" data-id="mytabs" closable = true></afx-tab-bar>
<afx-tree-view data-id="mytree"> </afx-tree-view>
</afx-vbox>
<afx-resizer data-width = "5" ></afx-resizer>
<afx-vbox>
<afx-button data-height="30" text="Read more" iconclass="fa fa-camera-retro fa-lg" id="button"></afx-button>
<afx-button data-height="30" text="__(Read more)" iconclass="fa fa-camera-retro fa-lg" id="button"></afx-button>
<afx-switch enable= true data-height="30"></afx-switch>
<afx-calendar-view></afx-calendar-view>
<afx-resizer data-height = "5" ></afx-resizer>

View File

@ -8,10 +8,11 @@ class Files extends this.OS.GUI.BaseApplication
@view = @find "fileview"
@navinput = @find "navinput"
@navbar = @find "nav-bar"
@currdir = if @args and @args.length > 0 then @args[0].asFileHandler() else "home:///".asFileHandler()
@currdir = if @args and @args.length > 0 then @args[0].asFileHandler() else "home://".asFileHandler()
@favo = @find "favouri"
@clipboard = undefined
@viewType = @_api.switcher "icon", "list", "tree"
@viewType.list = true
@apps = []
@view.contextmenuHandler = (e, m) ->
@ -42,7 +43,7 @@ class Files extends this.OS.GUI.BaseApplication
return unless e.child
return if e.child.filename is "[..]"
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
return me.error __("Resource not found {0}", e.child.path) if d.error
f d.result
@view.set "onfileselect", (e) ->
@ -77,6 +78,12 @@ class Files extends this.OS.GUI.BaseApplication
@bindKey "CTRL-C", () -> me.actionEdit "#{me.name}-copy"
@bindKey "CTRL-P", () -> me.actionEdit "#{me.name}-paste"
(@find "btgrid").set "onbtclick", (e) ->
me.view.set 'view', "icon"
me.viewType.icon = true
(@find "btlist").set "onbtclick", (e) ->
me.view.set 'view', "list"
me.viewType.list = true
@chdir null
applySetting: (k) ->
@ -92,7 +99,7 @@ class Files extends this.OS.GUI.BaseApplication
dir = if p then p.asFileHandler() else me.currdir
dir.read (d) ->
if(d.error)
return me.error "Resource not found #{p}"
return me.error __("Resource not found {0}", p)
me.currdir = dir
if not dir.isRoot()
@ -110,28 +117,28 @@ class Files extends this.OS.GUI.BaseApplication
#console.log file
me = @
arr = {
text: "File",
text: "__(File)",
child: [
{ text: "New file", dataid: "#{@name}-mkf", shortcut: 'C-F' },
{ text: "New folder", dataid: "#{@name}-mkdir", shortcut: 'C-D' },
{ text: "Open with", dataid: "#{@name}-open", child:@apps },
{ text: "Upload", dataid: "#{@name}-upload", shortcut: 'C-U' },
{ text: "Download", dataid: "#{@name}-download" },
{ text: "Share file", dataid: "#{@name}-share", shortcut: 'C-S' },
{ text: "Properties", dataid: "#{@name}-info", shortcut: 'C-I' }
{ text: "__(New file)", dataid: "#{@name}-mkf", shortcut: 'C-F' },
{ text: "__(New folder)", dataid: "#{@name}-mkdir", shortcut: 'C-D' },
{ text: "__(Open with)", dataid: "#{@name}-open", child: @apps },
{ text: "__(Upload)", dataid: "#{@name}-upload", shortcut: 'C-U' },
{ text: "__(Download)", dataid: "#{@name}-download" },
{ text: "__(Share file)", dataid: "#{@name}-share", shortcut: 'C-S' },
{ text: "__(Properties)", dataid: "#{@name}-info", shortcut: 'C-I' }
], onmenuselect: (e) -> me.actionFile e.item.data.dataid
}
return arr
mnEdit: () ->
me = @
{
text: "Edit",
text: "__(Edit)",
child: [
{ text: "Rename", dataid: "#{@name}-mv", shortcut: 'C-R' },
{ text: "Delete", dataid: "#{@name}-rm", shortcut: 'C-M' },
{ text: "Cut", dataid: "#{@name}-cut", shortcut: 'C-X' },
{ text: "Copy", dataid: "#{@name}-copy", shortcut: 'C-C' },
{ text: "Paste", dataid: "#{@name}-paste", shortcut: 'C-P' }
{ text: "__(Rename)", dataid: "#{@name}-mv", shortcut: 'C-R' },
{ text: "__(Delete)", dataid: "#{@name}-rm", shortcut: 'C-M' },
{ text: "__(Cut)", dataid: "#{@name}-cut", shortcut: 'C-X' },
{ text: "__(Copy)", dataid: "#{@name}-copy", shortcut: 'C-C' },
{ text: "__(Paste)", dataid: "#{@name}-paste", shortcut: 'C-P' }
], onmenuselect: (e) -> me.actionEdit e.item.data.dataid
}
menu: () ->
@ -140,19 +147,19 @@ class Files extends this.OS.GUI.BaseApplication
@mnFile(),
@mnEdit(),
{
text: "View",
text: "__(View)",
child: [
{ text: "Refresh", dataid: "#{@name}-refresh" },
{ text: "Sidebar", switch: true, checked: @setting.sidebar, dataid: "#{@name}-side" },
{ text: "Navigation bar", switch: true, checked: @setting.nav, dataid: "#{@name}-nav" },
{ text: "Hidden files", switch: true, checked: @setting.showhidden, dataid: "#{@name}-hidden" },
{ text: "Type", child: [
{ text: "Icon view", radio: true, checked: @setting.view is 'icon', dataid: "#{@name}-icon", type: 'icon' },
{ text: "List view", radio:true, checked: @setting.view is 'list' or not @setting.view, dataid: "#{@name}-list", type: 'list' },
{ text: "Tree view", radio:true, checked: @setting.view is 'tree', dataid: "#{@name}-tree", type: 'tree' }
{ text: "__(Refresh)", dataid: "#{@name}-refresh" },
{ text: "__(Sidebar)", switch: true, checked: @setting.sidebar, dataid: "#{@name}-side" },
{ text: "__(Navigation bar)", switch: true, checked: @setting.nav, dataid: "#{@name}-nav" },
{ text: "__(Hidden files)", switch: true, checked: @setting.showhidden, dataid: "#{@name}-hidden" },
{ text: "__(Type)", child: [
{ text: "__(Icon view)", radio: true, checked: (() -> me.viewType.icon), dataid: "#{@name}-icon", type: 'icon' },
{ text: "__(List view)", radio:true, checked: (() -> me.viewType.list), dataid: "#{@name}-list", type: 'list' },
{ text: "__(Tree view)", radio:true, checked: (() -> me.viewType.tree), dataid: "#{@name}-tree", type: 'tree' }
], onmenuselect: (e) ->
me.view.set 'view', e.item.data.type
me.setting.view = e.item.data.type
me.viewType[e.item.data.type] = true
},
], onmenuselect: (e) -> me.actionView e
},
@ -171,12 +178,12 @@ class Files extends this.OS.GUI.BaseApplication
switch e.item.data.dataid
when "#{@name}-hidden"
#@.view.set "showhidden", e.item.data.checked
@registry "showhidden",e.item.data.checked
@registry "showhidden", e.item.data.checked
#@.setting.showhidden = e.item.data.checked
when "#{@name}-refresh"
@.chdir null
when "#{@name}-side"
@registry "sidebar",e.item.data.checked
@registry "sidebar", e.item.data.checked
#@setting.sidebar = e.item.data.checked
#@toggleSidebar e.item.data.checked
when "#{@name}-nav"
@ -195,8 +202,8 @@ class Files extends this.OS.GUI.BaseApplication
return if d is file.filename
file.path.asFileHandler()
.move "#{me.currdir.path}/#{d}", (r) ->
me.error "Fail to rename to #{d}: #{r.error}" if r.error
, "Rename", { label: "File name:", value: file.filename }
me.error __("Fail to rename to {0}: {1}", d, r.error) if r.error
, "__(Rename)", { label: "__(File name)", value: file.filename }
when "#{@name}-rm"
return unless file
@ -205,23 +212,23 @@ class Files extends this.OS.GUI.BaseApplication
return unless d
file.path.asFileHandler()
.remove (r) ->
me.error "Fail to delete #{file.filename}: #{r.error}" if r.error
, "Delete" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{file.filename} ?" }
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
,"__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-cut"
return unless file
@clipboard =
cut: true
file: file.path.asFileHandler()
@notify "File #{file.filename} cut"
@notify __("File {0} cut", file.filename)
when "#{@name}-copy"
return unless file
@clipboard =
cut: false
file: file.path.asFileHandler()
@notify "File #{file.filename} copied"
@notify __("File {0} copied", file.filename)
when "#{@name}-paste"
me = @
@ -230,9 +237,9 @@ class Files extends this.OS.GUI.BaseApplication
@clipboard.file # duplicate file check
.move "#{me.currdir.path}/#{@clipboard.file.basename}", (r) ->
me.clipboard = undefined
me.error "Fail to paste: #{r.error}" if r.error
me.error __("Fail to paste: {0}", r.error) if r.error
else
@notify "Copy not yet implemented"
@notify __("Copy not yet implemented")
@clipboard = undefined
else
@_api.handler.setting()
@ -246,16 +253,16 @@ class Files extends this.OS.GUI.BaseApplication
@openDialog "PromptDialog",
(d) ->
me.currdir.mk d, (r) ->
me.error "Fail to create #{d}: #{r.error}" if r.error
, "New folder", { label: "Folder name:" }
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New folder)", { label: "__(Folder name)" }
when "#{@name}-mkf"
@openDialog "PromptDialog",
(d) ->
fp = "#{me.currdir.path}/#{d}".asFileHandler()
fp.write "text/plain", (r) ->
me.error "Fail to create #{d}: #{r.error}" if r.error
, "New file", { label: "File name:" }
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New file)", { label: "__(File name)" }
when "#{@name}-info"
return unless file
@ -264,14 +271,14 @@ class Files extends this.OS.GUI.BaseApplication
when "#{@name}-upload"
me = @
@currdir.upload (r) ->
me.error "Faile to upload to: #{d}: #{r.error}" if r.error
me.error __("Fail to upload to {0}: {1}", d, r.error) if r.error
when "#{@name}-share"
me = @
return unless file and file.type is "file"
file.path.asFileHandler().publish (r) ->
return me.error "Cannot share file: #{r.error}" if r.error
return me.notify "Shared url: #{r.result}"
return me.error __("Cannot share file: {0}", r.error) if r.error
return me.notify __("Shared url: {0}", r.result)
when "#{@name}-download"
return unless file

View File

@ -29,9 +29,8 @@ afx-app-window[data-id ='files-app-window'] afx-grid-view afx-grid-row.grid_row_
}
afx-app-window[data-id ='files-app-window'] button{
height: 23px;
border-radius: 3px;
border-radius: 0;
padding-top:2px;
margin-left: 5px;
}
afx-app-window[data-id ='files-app-window'] input{

View File

@ -1,9 +1,12 @@
<afx-app-window data-id = "files-app-window" apptitle="Files" width="600" height="400">
<afx-vbox>
<afx-hbox data-height = "30" data-id = "nav-bar">
<afx-button data-width = "30" data-id = "btback" iconclass = "fa fa-arrow-left"></afx-button>
<afx-button data-width = "23" data-id = "btback" iconclass = "fa fa-arrow-left"></afx-button>
<input type = "text" data-id = "navinput"></input>
<div data-width = "5"></div>
<div data-width = "2"></div>
<afx-button data-width = "23" data-id = "btgrid" iconclass = "fa fa-th"></afx-button>
<div data-width = "2"></div>
<afx-button data-width = "23" data-id = "btlist" iconclass = "fa fa-th-list"></afx-button>
</afx-hbox>
<afx-hbox>
<afx-list-view data-id = "favouri" data-width = "150" min-width="100">

View File

@ -74,7 +74,7 @@ class MarkOn extends this.OS.GUI.BaseApplication
save: (file) ->
me = @
file.write (file.getb64 "text/plain"), (d) ->
return me.error "Error saving file #{file.basename}" if d.error
return me.error __("Error saving file {0}", file.basename) if d.error
file.dirty = false
file.text = file.basename
me.scheme.set "apptitle", "#{me.currfile.basename}"
@ -82,12 +82,12 @@ class MarkOn extends this.OS.GUI.BaseApplication
menu: () ->
me = @
menu = [{
text: "File",
text: "__(File)",
child: [
{ text: "Open", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "Open", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "Save", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "Save as", dataid: "#{@name}-Saveas", shortcut: "A-W" }
{ text: "__(New)", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" }
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
}]
@ -99,12 +99,12 @@ class MarkOn extends this.OS.GUI.BaseApplication
me.openDialog "FileDiaLog", (d, n) ->
me.currfile.setPath "#{d}/#{n}"
me.save me.currfile
, "Save as", { file: me.currfile }
, __("Save as"), { file: me.currfile }
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, "Open file"
, __("Open file")
when "#{@name}-Save"
@currfile.cache = @editor.value()
return @save @currfile if @currfile.basename
@ -125,7 +125,7 @@ class MarkOn extends this.OS.GUI.BaseApplication
if d
me.currfile.dirty = false
me.quit()
, "Quit", { text: "Quit without saving ?" }
, __("Quit"), { text: __("Quit without saving ?") }
MarkOn.dependencies = [ "mde/simplemde.min" ]

View File

@ -9,24 +9,67 @@ class RepositoryDialog extends this.OS.GUI.BaseDialog
main: () ->
me = @
@list = @find "repo-list"
ls = ({ text: v.name, iconclass: "fa fa-link", url: v.url
} for v in @systemsetting.system.repositories)
@url = @find "repo-url"
@list.set "onlistselect", (e) ->
($ me.url).html e.data.url
@list.set "items", ls
@list.set "onlistdbclick", (e) ->
selidx = me.list.get "selidx"
return unless selidx >= 0
sel = me.systemsetting.system.repositories[selidx]
me.openDialog "PromptDialog", (e) ->
m = e.match /\[([^\]]*)\]\s*(.*)/
return me.error "Wrong format: it should be [name] url" if not m or m.length isnt 3
sel.name = m[1]
sel.text = sel.name
sel.url = m[2]
me.refreshList()
, __("Edit repository"), { label: __("Format : [name] url"), value: "[#{e.data.text}] #{e.data.url}" }
@list.set "buttons", [
{
text: "+",
onbtclick: () ->
me.openDialog "PromptDialog", (e) ->
m = e.match /\[([^\]]*)\]\s*(.*)/
return me.error __("Wrong format: it should be [name] url") if not m or m.length isnt 3
me.systemsetting.system.repositories.push {
name: m[1],
url: m[2],
text: m[1],
i: me.systemsetting.system.repositories.length
}
me.refreshList()
, __("Add repository"), { label: __("Format : [name] url") }
},
{
text: "-",
onbtclick: () ->
selidx = me.list.get "selidx"
return unless selidx >= 0
me.systemsetting.system.repositories.splice selidx, selidx
me.refreshList()
}
]
(@find "btquit").set "onbtclick", (e) -> me.quit()
@refreshList()
refreshList: () ->
ls = ({
text: v.name,
iconclass: "fa fa-link",
url: v.url,
complex: true,
detail: [{ text: v.url }]
} for v in @systemsetting.system.repositories)
@list.set "items", ls
onexit: (e) ->
@parent.repo.set "items", @systemsetting.system.repositories
@parent.dialog = undefined if @parent
RepositoryDialog.scheme = """
<afx-app-window data-id = "repository-dialog-win" apptitle="Repositories" width="250" height="250">
<afx-app-window data-id = "repository-dialog-win" apptitle="__(Repositories)" width="250" height="250">
<afx-vbox >
<afx-list-view data-id="repo-list"></afx-list-view>
<div data-id="repo-url" data-height="grow"></div>
<afx-hbox data-height = "30">
<afx-button data-id = "btadd" text = "[+]" data-width="30"></afx-button>
<afx-button data-id = "btdel" text = "[-]" data-width="30"></afx-button>
<div></div>
<afx-button data-id = "btquit" text = "Cancel" data-width="50"></afx-button>
</afx-hbox>
<div style = "text-align:right; padding:5px" data-height="30" >
<afx-button data-id = "btquit" text = "__(Cancel)"></afx-button>
</div>
</afx-vbox>
</afx-app-window>
"""

View File

@ -7,12 +7,6 @@ class MarketPlace extends this.OS.GUI.BaseApplication
me = @
@installdir = @systemsetting.system.pkgpaths.user
# test repository
@systemsetting.system.repositories.push {
text: "Antos repository"
url: "https://os.localhost:9195/repo/packages.json"
name: "Antos repository"
selected:true
} if @systemsetting.system.repositories.length is 0
@repo = @find "repo"
@repo.set "onlistselect", (e) ->
return unless e.data
@ -49,12 +43,13 @@ class MarketPlace extends this.OS.GUI.BaseApplication
v.iconclass = "fa fa-adn"
me.applist.set "items", d
, (e, s) ->
me.error "Fail to fetch packages list from: #{url}"
me.error __("Fail to fetch packages list from: {0}", url)
appDetail: (d) ->
($ @container).css "visibility", "visible"
( $ @appname ).html d.name
($ @appdesc).html d.description if d.description
($ @appdesc).prepend ($ "<img/>").attr("src", d.screenshot) if d.screenshot
if @systemsetting.system.packages[d.className]
($ @btinstall).hide()
@ -72,8 +67,8 @@ class MarketPlace extends this.OS.GUI.BaseApplication
menu: () ->
me = @
return [
{ text: "Options", child: [
{ text: "Repositories", shortcut: "C-R" }
{ text: "__(Options)", child: [
{ text: "__(Repositories)", shortcut: "C-R" }
] , onmenuselect: (e) ->
me.openDialog "RepositoryDialog"
}
@ -95,13 +90,12 @@ class MarketPlace extends this.OS.GUI.BaseApplication
else
files.push name
idx = files.indexOf "package.json"
return me.error "Invalid package: Meta data file not found" if idx < 0
return me.error __("Invalid package: Meta data file not found") if idx < 0
# create all directory
me.mkdirs app.className, dir, () ->
me.installFile app.className, zip, files, () ->
zip.file("package.json").async("string").then (d) ->
v = JSON.parse d
console.log v
v.text = v.name
v.filename = app.className
v.type = "app"
@ -109,32 +103,32 @@ class MarketPlace extends this.OS.GUI.BaseApplication
v.iconclass = "fa fa-adn" unless v.iconclass or v.icon
v.path = pth
me.systemsetting.system.packages[app.className] = v
me.notify "Application installed"
me.notify __("Application installed")
me._gui.refreshSystemMenu()
me.appDetail app
.catch (err) ->
me.error "Error reading package meta data: " + err
me.error __("Error reading package meta data: {0}", err)
, (err, s) ->
return me.error "Cannot down load the app #{err}" if err
return me.error __("Cannot down load the app {0}", err) if err
uninstall: (e) ->
me = @
app = @applist.get "selected"
name = app.className
return unless app
app = @systemsetting.system.packages[app.className]
sel = @applist.get "selected"
name = sel.className
return unless sel
app = @systemsetting.system.packages[sel.className]
return unless app
@openDialog "YesNoDialog",
(d) ->
return unless d
app.path.asFileHandler().remove (r) ->
me.error "Cannot uninstall package: #{r.error}" if r.error
me.notify "Package uninstalled"
me.systemsetting.system.packages[name] = undefined
return me.error __("Cannot uninstall package: {0}", r.error) if r.error
me.notify __("Package uninstalled")
delete me.systemsetting.system.packages[name]
me._gui.refreshSystemMenu()
me.appDetail app
, "Uninstall" ,
{ text: "Uninstall : #{app.name} ?" }
me.appDetail sel
, __("Uninstall") ,
{ text: __("Uninstall : {0}?", app.name) }
mkdirs: (n, list, f) ->
me = @
if list.length is 0
@ -145,7 +139,7 @@ class MarketPlace extends this.OS.GUI.BaseApplication
dname = dir.basename
path.asFileHandler().mk dname, (r) ->
return me.mkdirs n, list, f if r.result
me.error "Cannot create #{path}/#{dir}"
me.error __("Cannot create {0}", "#{path}/#{dir}")
installFile: (n, zip, files, f) ->
me = @
@ -159,7 +153,8 @@ class MarketPlace extends this.OS.GUI.BaseApplication
fp.cache = new Blob [d], { type: "octet/stream" }
fp.write "text/plain", (r) ->
return me.installFile n, zip, files, f if r.result
me.error "Cannot install #{path}"
me.error __("Cannot install {0}", path)
MarketPlace.dependencies = [ "jszip.min" ]
MarketPlace.singleton = true
this.OS.register "MarketPlace", MarketPlace

View File

@ -37,6 +37,10 @@ afx-app-window[data-id="marketplace-win"] p[data-id='app-desc'] {
padding:10px;
padding-top: 0;
}
afx-app-window[data-id="marketplace-win"] p[data-id='app-desc'] img{
display: block;
margin-bottom: 10px;
}
afx-app-window[data-id="marketplace-win"] ul[data-id='app-detail'] {
padding:0;
padding-left:10px;
@ -56,4 +60,8 @@ afx-app-window[data-id="marketplace-win"] ul[data-id='app-detail'] span{
}
afx-app-window[data-id="marketplace-win"] span.info-header{
font-weight: bold;
}
afx-app-window[data-id = "repository-dialog-win"] afx-list-view[data-id="repo-list"] ul.complex-content > li{
font-size: 11px;
font-style: italic;
}

View File

@ -8,10 +8,11 @@
<afx-vbox data-id = "container">
<div data-id = "appname" data-height = "25"></div>
<afx-hbox data-height = "25">
<afx-button data-id = "bt-remove" text = "Uninstall" data-width = "65"></afx-button>
<afx-button data-id = "bt-exec" text = "Launch" data-width = "50"></afx-button>
<afx-button data-id = "bt-install" text = "Install" data-width = "50"></afx-button>
<div></div>
<div style = "text-align:left;">
<afx-button data-id = "bt-remove" text = "__(Uninstall)"></afx-button>
<afx-button data-id = "bt-exec" text = "__(Launch)"></afx-button>
<afx-button data-id = "bt-install" text = "__(Install)" ></afx-button>
</div>
</afx-hbox>
<div>
<p data-id = "app-desc"></p>

View File

@ -58,7 +58,7 @@ class NotePad extends this.OS.GUI.BaseApplication
stup = (e) ->
c = me.editor.session.selection.getCursor()
l = me.editor.session.getLength()
$(stat).html "Row #{c.row}, col #{c.column}, lines: #{l}"
stat.set "text", __("Row {0}, col {1}, lines: {2}", c.row, c.column, l)
stup(0)
@.editor.getSession().selection.on "changeCursor", (e) -> stup(e)
@editormux = false
@ -79,7 +79,7 @@ class NotePad extends this.OS.GUI.BaseApplication
return unless e.child
return if e.child.filename is "[..]"
e.child.path.asFileHandler().read (d) ->
return me.error "Resource not found #{e.child.path}" if d.error
return me.error __("Resource not found {0}", e.child.path) if d.error
f d.result
@fileview.set "onfileopen", (e) ->
return if e.type is "dir"
@ -101,7 +101,7 @@ class NotePad extends this.OS.GUI.BaseApplication
me.openDialog "YesNoDialog", (d) ->
return me.closeTab it if d
me.editor.focus()
, "Close tab", { text: "Close without saving ?" }
, __("Close tab"), { text: __("Close without saving ?") }
return false
#@tabarea.set "closable", true
@bindKey "ALT-N", () -> me.actionFile "#{me.name}-New"
@ -123,16 +123,17 @@ class NotePad extends this.OS.GUI.BaseApplication
contextMenu: () ->
[
{ text: "New file", dataid: "#{@name}-mkf" },
{ text: "New folder", dataid: "#{@name}-mkd" },
{ text: "Delete", dataid: "#{@name}-rm" }
{ text: "Refresh", dataid: "#{@name}-refresh" }
{ text: __("New file"), dataid: "#{@name}-mkf" },
{ text: __("New folder"), dataid: "#{@name}-mkd" },
{ text: __("Delete"), dataid: "#{@name}-rm" }
{ text: __("Refresh"), dataid: "#{@name}-refresh" }
]
contextAction: (e) ->
me = @
file = @fileview.get "selectedFile"
dir = if file then file.path.asFileHandler() else (@fileview.get "path").asFileHandler()
console.log dir
dir = dir.parent().asFileHandler() if file and file.type isnt "dir"
switch e.item.data.dataid
@ -140,16 +141,16 @@ class NotePad extends this.OS.GUI.BaseApplication
@openDialog "PromptDialog",
(d) ->
dir.mk d, (r) ->
me.error "Fail to create #{d}: #{r.error}" if r.error
, "New folder"
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New folder)"
when "#{@name}-mkf"
@openDialog "PromptDialog",
(d) ->
fp = "#{dir.path}/#{d}".asFileHandler()
fp.write "", (r) ->
me.error "Fail to create #{d}: #{r.error}" if r.error
, "New file"
me.error __("Fail to create {0}: {1}", d, r.error) if r.error
, "__(New file)"
when "#{@name}-rm"
return unless file
@openDialog "YesNoDialog",
@ -157,16 +158,16 @@ class NotePad extends this.OS.GUI.BaseApplication
return unless d
file.path.asFileHandler()
.remove (r) ->
me.error "Fail to delete #{file.filename}: #{r.error}" if r.error
, "Delete" ,
{ iconclass: "fa fa-question-circle", text: "Do you really want to delete: #{file.filename} ?" }
me.error __("Fail to delete {0}: {1}", file.filename, r.error) if r.error
, "__(Delete)" ,
{ iconclass: "fa fa-question-circle", text: __("Do you really want to delete: {0}?", file.filename) }
when "#{@name}-refresh"
@.chdir ( @fileview.get "path" )
save: (file) ->
me = @
file.write "text/plain", (d) ->
return me.error "Error saving file #{file.basename}" if d.error
return me.error __("Error saving file {0}", file.basename) if d.error
file.dirty = false
file.text = file.basename
me.tabarea.update()
@ -228,7 +229,7 @@ class NotePad extends this.OS.GUI.BaseApplication
dir = pth.asFileHandler()
dir.read (d) ->
if(d.error)
return me.error "Resource not found #{p}"
return me.error __("Resource not found {0}", p)
if not dir.isRoot()
p = dir.parent().asFileHandler()
p.filename = "[..]"
@ -242,12 +243,12 @@ class NotePad extends this.OS.GUI.BaseApplication
menu: () ->
me = @
menu = [{
text: "File",
text: "__(File)",
child: [
{ text: "New", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "Open", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "Save", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "Save as", dataid: "#{@name}-Saveas", shortcut: "A-W" }
{ text: "__(New)", dataid: "#{@name}-New", shortcut: "A-N" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Save)", dataid: "#{@name}-Save", shortcut: "C-S" },
{ text: "__(Save as)", dataid: "#{@name}-Saveas", shortcut: "A-W" }
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
}]
@ -267,12 +268,12 @@ class NotePad extends this.OS.GUI.BaseApplication
me.tabarea.replaceItem me.currfile, file, false
me.currfile = file
me.save me.currfile
, "Save as", { file: me.currfile }
, "__(Save as)", { file: me.currfile }
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, "Open file"
, "__(Open file)"
when "#{@name}-Save"
@currfile.cache = @editor.getValue()
return @save @currfile if @currfile.basename
@ -292,7 +293,7 @@ class NotePad extends this.OS.GUI.BaseApplication
if d
v.dirty = false for v in dirties
me.quit()
, "Quit", { text: "Ignore all #{dirties.length} unsaved files ?" }
, "__(Quit)", { text: __("Ignore all {0} unsaved files ?", dirties.length) }
NotePad.singleton = false
NotePad.dependencies = [

View File

@ -11,7 +11,7 @@ afx-app-window[data-id="notepad"] afx-resizer{
background-color: transparent;
border-right: 1px solid #a6a6a6;
}
afx-app-window[data-id="notepad"] span[data-id="editorstat"]{
afx-app-window[data-id="notepad"] afx-label[data-id="editorstat"]{
padding:5px;
display: inline-block;
}
@ -22,7 +22,7 @@ afx-app-window[data-id="notepad"] .afx-window-content {
background-color: #f6F6F6;
}
afx-tab-container[data-id="tabarea"] afx-list-view > div.list-container > ul > li {
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li {
background-color: #dfdfdf;
color:#272822;
border: 0;
@ -30,16 +30,16 @@ afx-tab-container[data-id="tabarea"] afx-list-view > div.list-container > ul >
border-right: 1px solid #a6a6a6;
border-radius: 0;
}
afx-tab-container[data-id="tabarea"] afx-list-view{
afx-tab-bar[data-id="tabarea"] afx-list-view{
padding:0;
margin: 0;
border-left: 0;
border-bottom: 1px solid #a6a6a6;
}
/*afx-tab-container[data-id="tabarea"] afx-list-view i.closable:before{
/*afx-tab-bar[data-id="tabarea"] afx-list-view i.closable:before{
color: white;
}*/
afx-tab-container[data-id="tabarea"] afx-list-view > div.list-container > ul > li.selected {
afx-tab-bar[data-id="tabarea"] afx-list-view > div.list-container > ul > li.selected {
background-color: #f6F6F6;
border-radius: 0;
}

View File

@ -6,10 +6,10 @@
</afx-vbox>
<afx-resizer data-width = "3" ></afx-resizer>
<afx-vbox>
<afx-tab-container data-id="tabarea" data-height="26" closable = true></afx-tab-container>
<afx-tab-bar data-id="tabarea" data-height="26" closable = true></afx-tab-bar>
<div data-id="datarea"></div>
<afx-hbox data-height="30" data-id="bottom-vbox">
<div ><span data-id = "editorstat"></span></div>
<afx-label data-id="editorstat"></afx-label>
<afx-list-view data-width="160" data-id = "themelist" dropdown = "true" width="135"></afx-list-view>
<afx-list-view data-width="125" data-id = "modelist" dropdown = "true" width="100"></afx-list-view>

View File

@ -21,7 +21,7 @@ class Preview extends this.OS.GUI.BaseApplication
file.info.size = (file.info.size / 1024).toFixed(2)
me.renderFile file
, (err) ->
me.error "File not found #{file.path}"
me.error __("File not found {0}", file.path)
renderFile: (file) ->
mime = file.info.mime
@ -31,7 +31,7 @@ class Preview extends this.OS.GUI.BaseApplication
else if mime.match /image\/.*/g
@renderImage file
else
@notify "Mime type #{file.info.mime} is not support"
@notify __("Mime type {0} is not supported", file.info.mime)
setStatus: (t) ->
($ @status).html t
@ -68,7 +68,7 @@ class Preview extends this.OS.GUI.BaseApplication
fn(p+1)
fn(1)
.catch (err) ->
me.error "Cannot render the PDF file"
me.error __("Cannot render the PDF file")
me._api.loaded q, "FAIL"
, "binary"
@ -96,23 +96,22 @@ class Preview extends this.OS.GUI.BaseApplication
menu: () ->
me = @
menu = [{
text: "File",
text: "__(File)",
child: [
{ text: "Open", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "Close", dataid: "#{@name}-Close", shortcut: "C-X" },
{ text: "__(Open)", dataid: "#{@name}-Open", shortcut: "A-O" },
{ text: "__(Close)", dataid: "#{@name}-Close", shortcut: "C-X" },
],
onmenuselect: (e) -> me.actionFile e.item.data.dataid
}]
menu
actionFile: (e) ->
console.log e
me = @
switch e
when "#{@name}-Open"
@openDialog "FileDiaLog", ( d, f ) ->
me.open "#{d}/#{f}".asFileHandler()
, "Open file", { mimes: me.meta().mimes }
, __("Open file"), { mimes: me.meta().mimes }
when "#{@name}-Close"
@quit()

View File

@ -0,0 +1,78 @@
class AppearanceHandler extends SettingHandler
constructor:(scheme, parent) ->
super(scheme, parent)
me = @
@wplist = @find "wplist"
@wpreview = @find "wp-preview"
@wpsize = @find "wpsize"
@wprepeat = @find "wprepeat"
@themelist = @find "theme-list"
@syswp = undefined
@wplist.set "onlistselect", (e) ->
$(me.wpreview).css("background-image", "url(#{me.parent._api.handler.get}/#{e.data.path})" )
.css("background-size", "cover")
me.parent.systemsetting.appearance.wp.url = e.data.path
me.parent._gui.wallpaper()
@wplist.set "buttons", [
{
text: "+", onbtclick: (e) ->
me.parent.openDialog "FileDiaLog", (d, n, p) ->
me.parent.systemsetting.appearance.wps.push p
me.render()
, __("Select image file"), { mimes: ["image/.*"] }
}
]
@wpsize.set "onlistselect", (e) ->
me.parent.systemsetting.appearance.wp.size = e.data.text
me.parent._gui.wallpaper()
sizes = [
{ text: "cover", selected: me.parent.systemsetting.appearance.wp.size is "cover" },
{ text: "auto", selected: me.parent.systemsetting.appearance.wp.size is "auto" },
{ text: "contain", selected: me.parent.systemsetting.appearance.wp.size is "contain" }
]
@wpsize.set "items", sizes
repeats = [
{ text: "repeat", selected: me.parent.systemsetting.appearance.wp.repeat is "repeat" },
{ text: "repeat-x", selected: me.parent.systemsetting.appearance.wp.repeat is "repeat-x" },
{ text: "repeat-y", selected: me.parent.systemsetting.appearance.wp.repeat is "repeat-y" },
{ text: "no-repeat", selected: me.parent.systemsetting.appearance.wp.repeat is "no-repeat" }
]
@wprepeat.set "items", repeats
@wprepeat.set "onlistselect", (e) ->
me.parent.systemsetting.appearance.wp.repeat = e.data.text
me.parent._gui.wallpaper()
@themelist.set "items" , [{ text: "antos", selected: true }]
render: () ->
me = @
if not @syswp
path = "os://resources/themes/system/wp"
path.asFileHandler().read (d) ->
me.parent.error __("Cannot read wallpaper list from {0}", path) if d.error
for v in d.result
v.text = v.filename
v.selected = true if v.path is me.parent.systemsetting.appearance.wp.url
v.iconclass = "fa fa-file-image-o"
me.syswp = d.result
me.wplist.set "items", me.getwplist()
else
me.wplist.set "items", me.getwplist()
getwplist: () ->
list = []
for v in @parent.systemsetting.appearance.wps
file = v.asFileHandler()
list.push
text: file.basename,
path: file.path
selected: file.path is @parent.systemsetting.appearance.wp.url,
iconclass: "fa fa-file-image-o"
list = list.concat @syswp
return list

View File

@ -0,0 +1,21 @@
class LocaleHandler extends SettingHandler
constructor:(scheme, parent) ->
super(scheme, parent)
me = @
@lglist = @find "lglist"
@localelist = undefined
@lglist.set "onlistselect", (e) ->
me.parent._api.setLocale e.data.text
render: () ->
me = @
if not @localelist
path = "os://resources/languages"
path.asFileHandler().read (d) ->
return me.parent.error __("Cannot fetch system locales: {0}", d.error) if d.derror
for v in d.result
v.text = v.filename.replace /\.json$/g, ""
v.selected = v.text is me.parent.systemsetting.system.locale
me.localelist = d.result
me.lglist.set "items", me.localelist
else
me.lglist.set "items", me.localelist

View File

@ -0,0 +1,11 @@
coffee_files = main.coffee AppearanceHandler.coffee VFSHandler.coffee LocaleHandler.coffee StartupHandler.coffee
jsfiles =
cssfiles = main.css
copyfiles = scheme.html package.json schemes
PKG_NAME=Setting
include ../pkg.mk

View File

@ -0,0 +1,76 @@
class StartupHandler extends SettingHandler
constructor:(scheme, parent) ->
super(scheme, parent)
me = @
@srvlist = @find "srvlist"
@applist = @find "applist"
@srvlist.set "buttons", [
{
text: "+", onbtclick: (e) ->
services = []
for k, v of me.parent.systemsetting.system.packages
if v.services
srvs = ({ text: "#{k}/#{x}", iconclass:"fa fa-tasks" } for x in v.services)
services = services.concat srvs
me.parent.openDialog me.mkdialog(), (d) ->
me.parent.systemsetting.system.startup.services.push d
me.render()
, "__(Add service)", services
},
{
text: "-", onbtclick: (e) ->
selidx = me.srvlist.get "selidx"
return unless selidx >= 0
me.parent.systemsetting.system.startup.services.splice selidx,1
me.render()
}
]
@applist.set "buttons", [
{
text: "+", onbtclick: (e) ->
apps = ( { text: k, iconclass: v.iconclass } for k, v of me.parent.systemsetting.system.packages )
me.parent.openDialog me.mkdialog(), (d) ->
me.parent.systemsetting.system.startup.apps.push d
me.render()
, "__(Add application)", apps
},
{
text: "-", onbtclick: (e) ->
selidx = me.applist.get "selidx"
return unless selidx >= 0
me.parent.systemsetting.system.startup.apps.splice selidx,1
me.render()
}
]
render: () ->
@srvlist.set "items", ( { text:v } for v in @parent.systemsetting.system.startup.services )
@applist.set "items", ( { text:v } for v in @parent.systemsetting.system.startup.apps )
mkdialog: () ->
return @parent._gui.mkdialog {
name: "StartupDialog",
layout: {
tags: [
{ tag: "afx-list-view" }
],
width: 250,
height: 200,
resizable: false,
buttons: [
{
label: "__(Ok)", onclick: (d) ->
sel = (d.find "content0").get "selected"
return d.error __("Please select an entry") unless sel
d.handler(sel.text) if d.handler
d.quit()
},
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
],
filldata: (dia) ->
(dia.find "content0").set "items", dia.data if dia.data
}
}

View File

@ -0,0 +1,99 @@
class VFSHandler extends SettingHandler
constructor:(scheme, parent) ->
super(scheme, parent)
me = @
@mplist = @find "mplist"
@dpath = @find "dpath"
@ppath = @find "ppath"
@mplist.set "buttons", [
{
text: "+",
onbtclick: (e) ->
me.parent.openDialog me.mkdialog(), (d) ->
me.parent.systemsetting.VFS.mountpoints.push {
text: d.name, path: d.path, iconclass: "fa fa-folder", type: "fs"
}
me.render()
, "__(Add mount point)"
},
{
text: "-",
onbtclick: (e) ->
selidx = me.mplist.get "selidx"
sel = me.mplist.get "selected"
return unless selidx >= 0
me.parent.openDialog "YesNoDialog", (d) ->
return unless d
me.parent.systemsetting.VFS.mountpoints.splice selidx, 1
me.render()
, "__(Remove)", { text: __("Remove: {0}?", sel.text) }
},
{
text: "",
iconclass: "fa fa-pencil",
onbtclick: (e) ->
sel = me.mplist.get "selected"
return unless sel
me.parent.openDialog me.mkdialog(), (d) ->
d.el.text = d.name
d.el.path = d.path
me.render()
, "__(Edit mount point)", sel
}
]
(@find "btndpath").set 'onbtclick', (e) ->
me.parent.openDialog "FileDiaLog", (d, n, p) ->
me.parent.systemsetting.desktop.path = p
me.parent._gui.refreshDesktop()
me.render()
, "__(Select a directory)", { mimes: ["dir"], hidden: true }
(@find "btnppath").set 'onbtclick', (e) ->
me.parent.openDialog "FileDiaLog", (d, n, p) ->
me.parent.systemsetting.system.pkgpaths.user = p
me.render()
, "__(Select a directory)", { mimes: ["dir"], hidden: true }
render: () ->
me = @
@mplist.set "items", @parent.systemsetting.VFS.mountpoints
@dpath.set "text", @parent.systemsetting.desktop.path
@ppath.set "text", @parent.systemsetting.system.pkgpaths.user
mkdialog: () ->
return @parent._gui.mkdialog {
name: "MountPointDialog",
layout: {
tags: [
{ tag: "afx-label", att: 'text="__(Name)" data-height="20"' },
{ tag: "input", att: "type='text' data-height='25'" },
{ tag: "afx-label", att: 'text="__(Path)" data-height="20"' },
{ tag: "input", att: "type='text' data-height='25'" }
],
width: 250,
height: 150,
resizable: false,
buttons: [
{
label: "__(Ok)", onclick: (d) ->
data = {
name: (d.find "content1").value,
path: (d.find "content3").value,
el: d.data
}
return d.error __("Please enter mount point name") unless data.name and data.name isnt ""
return d.error __("Please select a directory") unless data.path and data.path isnt ""
d.handler(data) if d.handler
d.quit()
},
{ label: "__(Cancel)", onclick: (d) -> d.quit() }
],
filldata: (dia) ->
$(dia.find "content3").click (e) ->
dia.openDialog "FileDiaLog", (d, n, p) ->
(dia.find "content3").value = p
, "__(Select a directory)", { mimes: ["dir"], hidden: true }
return unless dia.data
(dia.find "content1").value = dia.data.text if dia.data.text
(dia.find "content3").value = dia.data.path if dia.data.path
}
}

View File

@ -0,0 +1,52 @@
class SettingHandler
constructor:(@scheme, @parent) ->
find: (id) -> ($ "[data-id='#{id}']", @scheme)[0] if @scheme
render: () ->
class Setting extends this.OS.GUI.BaseApplication
constructor: (args) ->
super "Setting", args
main: () ->
me = @
@container = @find "container"
@container.setTabs [
{
text: "__(Appearance)",
iconclass: "fa fa-paint-brush",
url: "#{@path()}/schemes/appearance.html",
handler: (sch) ->
new AppearanceHandler sch, me
},
{
text: "__(VFS)",
iconclass: "fa fa-inbox" ,
url: "#{@path()}/schemes/vfs.html" ,
handler: (sch) ->
new VFSHandler sch, me
},
{
text: "__(Languages)",
iconclass: "fa fa-globe",
url: "#{@path()}/schemes/locale.html",
handler: (sch) ->
new LocaleHandler sch, me
},
{
text: "__(Startup)",
iconclass: "fa fa-cog",
url: "#{@path()}/schemes/startup.html",
handler: (sch) ->
new StartupHandler sch,me
}
]
(@find "btnsave").set "onbtclick", (e) ->
me._api.setting (d) ->
return me.error __("Cannot save system setting: {0}", d.error) if d.error
me.notify __("System setting saved")
Setting.singleton = true
this.OS.register "Setting", Setting

View File

@ -0,0 +1,55 @@
afx-app-window[data-id = "setting-window"] afx-tab-container afx-tab-bar afx-list-view > div > ul > li{
float:none;
border-radius: 0;
font-weight: bold;
padding-top:3px;
padding-bottom: 3px;
border:0;
}
afx-app-window[data-id = "setting-window"] afx-tab-container div[data-ref="container"]{
border-left: 1px solid #cbcbcb;
}
afx-app-window[data-id = "setting-window"] afx-label.header{
font-weight: bold;
}
afx-app-window[data-id = "setting-window"] div.footer{
border-right: 1px solid #cbcbcb;
}
/*APPEARANCE*/
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="appearance"] div[data-id = "wp-preview"]{
display: block;
border:1px solid #cbcbcb;
border-radius: 10px;
}
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="appearance"] afx-list-view[data-id="wplist"]
{
border:1px solid #cbcbcb;
padding:2px;
}
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="appearance"] afx-resizer{
border:0;
background-color: transparent;
}
/*VFS*/
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="vfs"] afx-list-view[data-id="mplist"]
{
border: 1px solid #cbcbcb;
}
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="vfs"] afx-button.btnsel button{
border-radius: 0;
padding-top:2px;
padding-bottom: 2px;
}
/*LANGUAGES*/
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="locale"] afx-list-view[data-id="lglist"]
{
border: 1px solid #cbcbcb;
}
/*STARTUP*/
afx-app-window[data-id = "setting-window"] afx-vbox[data-id="startup"] afx-list-view
{
border: 1px solid #cbcbcb;
}

View File

@ -0,0 +1,13 @@
{
"app":"Setting",
"name":"System setting",
"description":"System setting",
"info":{
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"version":"0.1a",
"category":"System",
"iconclass":"fa fa-wrench",
"mimes":["none"]
}

View File

@ -0,0 +1,12 @@
<afx-app-window data-id = "setting-window" apptitle="Setting" width="600" height="400">
<afx-vbox>
<afx-tab-container data-id = "container" barwidth="120" bar="left"></afx-tab-container>
<afx-hbox data-height="35">
<div data-width = "120" class = "footer"></div>
<div style="text-align:right" >
<afx-button text="__(Save)" data-id="btnsave" iconclass="fa fa-save" style="margin-right:10px;" ></afx-button>
</div>
</afx-hbox>
</afx-vbox>
</afx-app-window>

View File

@ -0,0 +1,27 @@
<afx-vbox data-id="appearance">
<div data-height="5"></div>
<afx-hbox>
<div data-width="10"></div>
<afx-vbox>
<afx-label text = "__(Wallpaper)" iconclass = "fa fa-image" class = "header" data-height="23"></afx-label>
<afx-hbox>
<afx-list-view data-width="150" data-id="wplist"></afx-list-view>
<afx-resizer data-width="5"></afx-resizer>
<afx-vbox>
<div data-id = "wp-preview"></div>
<div data-height="5"></div>
<afx-hbox data-height="25">
<afx-list-view data-id = "wpsize" dropdown="true"></afx-list-view>
<div data-width="5"></div>
<afx-list-view data-id = "wprepeat" dropdown="true"></afx-list-view>
</afx-hbox>
</afx-vbox>
</afx-hbox>
<div data-height="5"></div>
<afx-label text = "__(Theme)" iconclass = "fa fa-window-restore" class = "header" data-height="23"></afx-label>
<afx-list-view data-height="30" data-id="theme-list" dropdown="true"></afx-list-view>
<div data-height="5"></div>
</afx-vbox>
<div data-width="10"></div>
</afx-hbox>
</afx-vbox>

View File

@ -0,0 +1,12 @@
<afx-vbox data-id="locale">
<div data-height="5"></div>
<afx-hbox>
<div data-width="10"></div>
<afx-vbox>
<afx-label text = "__(System locale)" iconclass = "fa fa-globe" class = "header" data-height="23"></afx-label>
<afx-list-view data-id="lglist"></afx-list-view>
<div data-height="10"></div>
</afx-vbox>
<div data-width="10"></div>
</afx-hbox>
</afx-vbox>

View File

@ -0,0 +1,15 @@
<afx-vbox data-id="startup">
<div data-height="5"></div>
<afx-hbox>
<div data-width="10"></div>
<afx-vbox>
<afx-label text = "__(Startup services)" iconclass = "fa fa-tasks" class = "header" data-height="23"></afx-label>
<afx-list-view data-id="srvlist"></afx-list-view>
<div data-height="5"></div>
<afx-label text = "__(Startup applications)" iconclass = "fa fa-adn" class = "header" data-height="23"></afx-label>
<afx-list-view data-id="applist"></afx-list-view>
<div data-height="10"></div>
</afx-vbox>
<div data-width="10"></div>
</afx-hbox>
</afx-vbox>

View File

@ -0,0 +1,26 @@
<afx-vbox data-id="vfs">
<div data-height="5"></div>
<afx-hbox>
<div data-width="10"></div>
<afx-vbox>
<afx-label text = "__(Mount points)" iconclass = "fa fa-folder" class = "header" data-height="23"></afx-label>
<afx-list-view data-id="mplist"></afx-list-view>
<div data-height="5"></div>
<afx-label text = "__(Desktop path)" iconclass = "fa fa-desktop" class = "header" data-height="23"></afx-label>
<afx-hbox data-height = "25" >
<div data-width="16"></div>
<afx-label data-id="dpath"></afx-label>
<afx-button text="" iconclass = "fa fa-arrow-up" data-id="btndpath" data-width="20" class="btnsel"></afx-button>
</afx-hbox>
<div data-height="5"></div>
<afx-label text = "__(Local packages path)" iconclass = "fa fa-cube" class = "header" data-height="23"></afx-label>
<afx-hbox data-height = "25" >
<div data-width="16"></div>
<afx-label data-id="ppath"></afx-label>
<afx-button text="" data-id="btnppath" iconclass = "fa fa-arrow-up" data-width="20" class="btnsel"></afx-button>
</afx-hbox>
<div data-height="10"></div>
</afx-vbox>
<div data-width="10"></div>
</afx-hbox>
</afx-vbox>

View File

@ -9,9 +9,11 @@ title:
coffee:
- mkdir build
for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done
for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done
- rm build/*.coffee.js
for f in $(coffee_files); do (cat "$${f}"; echo) >>"build/main.coffee";done
coffee --compile build/main.coffee
#for f in $(coffee_files); do (coffee -cs < $$f >build/"$$f.js");done
#for f in build/*.coffee.js; do (cat "$${f}"; echo) >> build/main.js; done
- rm build/*.coffee
js: coffee
for f in $(jsfiles); do (cat "$${f}"; echo) >> build/main.js; done

View File

@ -22,9 +22,10 @@ afx-apps-dock afx-button button{
background-color: transparent;
border:0;
}
afx-apps-dock afx-button .icon-style{
afx-apps-dock afx-button afx-label i.icon-style{
width: 24px;
height: 24px;
margin-left: 2px;
margin-bottom: 0px;
border:0;
}

View File

@ -1,7 +1,7 @@
afx-file-view {
position: relative;
}
afx-file-view div.status{
afx-file-view afx-label.status{
position: absolute;
bottom: 1px;
left:0px;

View File

@ -1,5 +1,5 @@
afx-list-view{
overflow:auto;
overflow:hidden;
padding: 5px;
display: block;
}
@ -11,6 +11,9 @@ afx-list-view div.list-container{
position: relative;
background-color: red;
}*/
afx-list-view > div.list-container{
overflow: auto;
}
afx-list-view > div.list-container > ul{
margin:0;
padding: 0;
@ -78,6 +81,9 @@ afx-list-view.dropdown {
padding:0;
margin: 0;
}
afx-list-view.dropdown > div.list-container{
overflow: visible;
}
afx-list-view.dropdown > div.list-container > ul{
max-height: 150px;
overflow-y: auto;
@ -90,6 +96,7 @@ afx-list-view.dropdown > div.list-container > ul{
border-radius: 3px;
padding:2px;
border-top-left-radius: 0px;
z-index: 10;
}
afx-list-view.dropdown > div.list-container > ul > li{
display: inline-block;
@ -132,3 +139,20 @@ afx-list-view ul.complex-content li{
afx-list-view > div.list-container > ul > li.selected ul.complex-content li{
color:white;
}
/*
afx-list-view div.button_container {
padding-top:2px;
border-top:1px solid #cbcbcb;
}
*/
afx-list-view div.button_container afx-button{
margin-right: 2px;
}
afx-list-view div.button_container afx-button button{
border-radius: 0;
padding-left:5px;
padding-top:1px;
padding-bottom: 1px;
padding-right: 5px;
}

View File

@ -18,8 +18,11 @@ afx-menu a afx-label{
afx-menu ul{
padding:0;
margin: 0;
display:inline-block;
}
afx-menu ul li{
white-space:nowrap;
}
afx-menu afx-switch span{
width: 20px;
height: 16px;

View File

@ -0,0 +1,18 @@
afx-tab-bar {
display: block;
width: 100%;
}
afx-tab-bar afx-list-view {
padding:0;
margin:0;
}
afx-tab-bar afx-list-view > div.list-container > ul > li{
float:left;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding-bottom: 2px;
padding-right:15px;
padding-top:2px;
border:1px solid #c3c3c3;
}

View File

@ -1,18 +1,3 @@
afx-tab-container {
afx-tab-container{
display: block;
width: 100%;
}
afx-tab-container afx-list-view {
padding:0;
margin:0;
}
afx-tab-container afx-list-view > div.list-container > ul > li{
float:left;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding-bottom: 2px;
padding-right:15px;
padding-top:2px;
border:1px solid #c3c3c3;
}

View File

@ -5,9 +5,6 @@ html,body{
font-size: 13px;
width: 100%;
height: 100%;
background-image: url(wp2.jpg);
background-size: cover;
background-repeat: repeat;
overflow: hidden;
}
#wrapper{

View File

Before

Width:  |  Height:  |  Size: 434 KiB

After

Width:  |  Height:  |  Size: 434 KiB

Some files were not shown because too many files have changed in this diff Show More