1
0
mirror of https://shylinux.com/x/volcanos synced 2025-04-25 08:48:06 +08:00
This commit is contained in:
harveyshao 2022-05-14 15:23:18 +08:00
parent ac8c1cdb55
commit afe84a7730
14 changed files with 116 additions and 86 deletions

View File

@ -538,7 +538,6 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
}
break
case "username":
// item.inner = can.user.info.usernick
can.page.Append(can, target, [
can.base.Copy({view: ["username", "div"], onclick: function(event) {
}, list: [{view: ["some", html.DIV, can.user.info.usernick]}, {img: "/share/local/avatar"}]})])
@ -565,16 +564,37 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
}
if ((type||subtype) == html.ITEM) { item.view = item.view||html.LIST
if (meta.action == "auto") {
meta.init = meta.init||function(item) { can.core.Timer(100, function() { item.click() }) }
meta.init = meta.init||function(item) { can.core.Timer(10, function() { item.click() }) }
}
if (decodeURIComponent(location.hash) == "#"+can.core.Keys(keys, item.name)) {
meta.init = meta.init||function(item) { can.core.Timer(30, function() { item.click() }) }
}
var _item = can.page.Append(can, target, [can.base.Copy({view: [html.ITEM, html.DIV, meta.name||meta], onclick: function(event) {
location.hash = can.core.Keys(keys, item.name)
if (meta.action == "open") {
if (can.misc.Search(can, "pod")) {
can.user.open("/chat/pod/"+can.misc.Search(can, "pod")+"/cmd/"+meta.index)
} else {
can.user.open("/chat/cmd/"+meta.index)
}
return
}
if (meta.action == "push") {
if (can.misc.Search(can, "pod")) {
can.user.jumps("/chat/pod/"+can.misc.Search(can, "pod")+"/cmd/"+meta.index)
} else {
can.user.jumps("/chat/cmd/"+meta.index)
}
return
}
switch (meta.type) {
case html.PLUGIN:
if (can.onmotion.cache(can, function() { return keys }, data.main)) { break }
if (can.base.Ext(meta.index) == "zml") {
can.page.Append(can, data.main, [{type: "iframe", src: "/chat/cmd/"+meta.index,
width: data.main.offsetWidth, height: data.main.offsetHeight,
if (can.base.Ext(meta.index) == nfs.ZML || can.base.Ext(meta.index) == nfs.IML) {
can.page.Append(can, data.main, [{type: html.IFRAME, src: "/chat/cmd/"+meta.index,
height: data.main.offsetHeight, width: data.main.offsetWidth,
}])
break
}
@ -605,6 +625,7 @@ Volcanos("onappend", {help: "渲染引擎", list: [], _init: function(can, meta,
_plugin: function(can, value, meta, cb, target) {
meta.feature = can.base.getValid(meta.feature, can.base.Obj(value.meta))||{}
meta.inputs = can.base.getValid(meta.inputs, can.base.Obj(value.list))||[]
meta.args = can.base.getValid(can.base.Obj(meta.args), can.base.Obj(meta.arg), can.base.Obj(value.args), can.base.Obj(value.arg))||[]
meta.display = meta.display||value.display
meta.height = meta.height||can.Conf(html.HEIGHT)

View File

@ -248,11 +248,11 @@ Volcanos("user", {help: "用户操作", agent: {
item._init = function(target) {
item.run = function(event, cmds, cb) {
can.request(event, function() { var value = {_handle: ice.TRUE, action: msg.Option(chat.ACTION)}
can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) {
item.name && item.value && (value[item.name] = item.value)
}); return value
}, msg, can.Option()), can.run(event, cmds, cb, true)
var _msg = can.request(event, {_handle: ice.TRUE, action: msg.Option(chat.ACTION)}, msg, can.Option())
can.page.Select(can, ui.table, html.OPTION_ARGS, function(item) {
item.name && item.value && _msg.Option(item.name, item.value)
})
can.run(event, cmds, cb, true)
}
if (item.name != "action" && item.name) {

View File

@ -90,6 +90,7 @@ fieldset.output div.status { display:none; }
fieldset.output div.toggle { display:none; }
fieldset.input { background-color:#0d4142a6; top:32px; }
fieldset.input.key.float div.action { display:none; }
fieldset.input div.output { max-height:400px; }
fieldset.input table { color:white; }
fieldset.input td { word-break:keep-all; }

View File

@ -125,6 +125,9 @@ Volcanos("onaction", {help: "交互操作", list: [], _init: function(can, cb, t
can.onengine.plugin(can, "alert", shy("提示", {}, ["text", "list", "back"], function(msg, cmds) {
can.user.alert(cmds[0])
}))
can.onengine.plugin(can, "plugin", shy("插件", {}, ["text", "list", "back"], function(msg, cmds) {
msg.Echo("hello world")
}))
can.onengine.plugin(can, "info", shy("信息", {}, ["text", "list", "back"], function(msg, cmds) {
msg.Echo("hello world")
}))

View File

@ -58,7 +58,11 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can.core.List(can.base.Obj(msg.Option(chat.STATE)||can.Conf(chat.STATE), [mdb.TIME, aaa.USERNICK]), function(item) {
if (item == aaa.AVATAR ) { if (can.user.isLocalFile) { return }
can.page.Append(can, target, [{view: can.base.join([chat.STATE, item]), list: [{img: ice.SP}], onmouseenter: function(event) {
can.onaction.carte(event, can, [can.page.Format(html.IMG, "/share/local/avatar", 160)])
if (msg.Option(aaa.AVATAR).indexOf("http") == 0) {
can.onaction.carte(event, can, [can.page.Format(html.IMG, msg.Option(aaa.AVATAR), 160)])
} else {
can.onaction.carte(event, can, [can.page.Format(html.IMG, "/share/local/avatar", 160)])
}
}}]); return
}
@ -83,9 +87,12 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
if (can.user.isExtension || can.user.isLocalFile) { return }
msg.Option(aaa.BACKGROUND) && can.onlayout.background(can, "/share/local/background", document.body)
},
_avatar: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return }
// can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar/"})
msg.Option(aaa.AVATAR) && can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar"})
_avatar: function(can, msg) { if (can.user.isExtension || can.user.isLocalFile) { return } if (!msg.Option(aaa.AVATAR)) { return }
if (msg.Option(aaa.AVATAR).indexOf("http") == 0) {
can.page.Modify(can, "div.state.avatar>img", {src: msg.Option(aaa.AVATAR)})
} else {
can.page.Modify(can, "div.state.avatar>img", {src: "/share/local/avatar"})
}
},
_menus: function(can, msg, target) {
can.setHeaderMenu(can.user.mod.isPod||can.user.isExtension||can.user.isMobile? [ctx.CONFIG]:

View File

@ -90,7 +90,7 @@ body.simple fieldset.inner>div.output td.project div.project { width:240px; }
body.simple fieldset.inner>div.output td.project div.project div.kind { padding:10px; }
body.simple fieldset.inner>div.output td.project div.project div.kind { color: white; font-size: 1.2rem; font-family: monospace; height:18px; }
body.simple fieldset.inner>div.output td.project div.project div.kind:first-child { position:sticky; top:0 }
body.simple fieldset.inner>div.output div.content { background-color:#263238; font-size:16px; }
body.simple fieldset.inner>div.output div.content { background-color:#263238c2; font-size:16px; }
body.simple fieldset.inner>div.output div.toggle { display:none; }
body.simple fieldset.inner>div.output div.toggle.profile { background-color:#664f4f45; display:block; }

View File

@ -276,7 +276,8 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, cb, target
var rest = can.ui.display.offsetHeight+can.ui._path.offsetHeight+can.ui._tabs.offsetHeight+5
if (can.user.mod.isCmd) { can.page.styleHeight(can, can.ui.project, height+2*html.ACTION_HEIGHT)
can.page.styleHeight(can, can.ui.content, (can.ui.project.offsetHeight||height)-rest)
can.page.styleHeight(can, can.ui.profile_output, can.ui.project.offsetHeight-html.ACTION_HEIGHT-2)
can.page.styleHeight(can, can.ui.profile_output, (can.ui.project.offsetHeight||height)-rest+html.ACTION_HEIGHT+6)
// can.page.styleHeight(can, can.ui.profile_output, can.ui.project.offsetHeight-html.ACTION_HEIGHT-2)
} else {
can.page.style(can, can.ui.content, can.user.mod.isCmd || can.user.isMobile? html.HEIGHT: html.MAX_HEIGHT, height)
can.page.styleHeight(can, can.ui.project, can.ui.content.offsetHeight+rest)

View File

@ -3,8 +3,12 @@ fieldset.vimer>div.output input.current {
padding:0; padding-left:11px; border:none; outline:none; margin:0; margin-top:-1px;
height:22px; position:absolute;
}
fieldset.vimer>div.output div.complete.insert {
display:block;
}
fieldset.vimer>div.output div.complete {
height:20px; position:absolute; left:32px; margin-top:20px;
display:none;
}
fieldset.vimer>div.output div.complete div.pre {
font-size:1.1rem; margin-left:5px; float:left;

View File

@ -40,6 +40,7 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
}, [""])
Volcanos("onkeymap", {help: "键盘交互", list: [],
_model: function(can, value) { can.Status("模式", can.mode = value)
can.page.Modify(can, can.ui.complete, {className: "complete"+ice.SP+can.mode}), value
return can.page.Modify(can, can.ui.current, {className: "current"+ice.SP+can.mode}), value
},
_plugin: function(event, can) { can.onkeymap._model(can, "plugin")
@ -197,10 +198,20 @@ Volcanos("onaction", {help: "控件交互", list: [nfs.SAVE, code.AUTOGEN, code.
key = can.base.trimSuffix(key, word)
key = can.base.trimSuffix(key, ".")
function update(target) { can.request(event, {pre: pre, end: end, key: key, word: word})
function update(target) { can.request(event, {pre: pre, end: end, key: key, word: word, file: can.Option(nfs.FILE)})
can.run(event, [ctx.ACTION, "complete"], function(msg) {
can.page.Appends(can, target, [{view: ["pre", html.DIV, pre]}])
can.onappend.table(can, msg, null, target)
msg.Length() == 0 && pre == "" && can.core.List(can.core.Value(can.onsyntax[can.parse], "prepare.keyword"), function(k) {
msg.Push(mdb.NAME, k)
})
can.onappend.table(can, msg, function(value, key, index) {
return {text: [value, html.TD], onclick: function(event) {
var left = can.ui.current.value.slice(0, event.target.selectionStart)+value
can.ui.current.value = can.current.text(left+can.ui.current.value.slice(event.target.selectionEnd))
can.ui.current.setSelectionRange(left.length, left.length)
can.ui.current.focus(), can.ui.content.scrollBy(-10000, 0)
}}
}, target)
}, true)
}
function select() {

View File

@ -16,6 +16,7 @@ fieldset.word ul.story[data-type=endmenu] { clear:both; }
fieldset.word p.story[data-name=inner] { background-color:#4b6c8a7a; padding:4px 10px; border-left:solid 4px blue; margin:10px 0px; }
fieldset.word p.story[data-name=inner]:hover { background-color:#c10c8a; cursor:copy; }
fieldset.word svg.story { display:block; float:left; }
fieldset.word svg.story { font-family:fangsong; }
fieldset.word video.story { max-height:320px; }
fieldset.word fieldset.story { margin:10px; }

View File

@ -114,8 +114,7 @@ Volcanos("onimport", {help: "导入数据", _init: function(can, msg, cb, target
chart: function(can, data, target) {
target.oncontextmenu = function(event) {
can.user.carteClient(event, can, kit.Dict(mdb.EXPORT, function(event, can, button) {
can.user.toPNG(can, can.user.prompt("please input file name", "hi")+".png", target.outerHTML,
parseInt(target.getAttribute(html.HEIGHT))||200, parseInt(target.getAttribute(html.WIDTH))||200)
can.onmotion.toimage(event, can, "hi.png", target)
}), [mdb.EXPORT])
}
},

View File

@ -5,10 +5,10 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
can._args = can.base.Copy({root: "ice", field: msg.append[0], split: ice.PS}, can.base.ParseURL(can._display))
can.dir_root = msg.Option(nfs.DIR_ROOT)||can._args.root||""
can._tree = can.onimport._tree(can, msg.Table(), can._args.field, can._args.split)
if (!can._tree[""]) { return }
can._tree[""].name = can._args.root
if (!can._tree[""]) { return } can._tree[""].name = can._args.root
can.size = 30, can.margin = 30
can.onmotion.hidden(can, can._action)
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
@ -59,10 +59,8 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
},
}, [""])
Volcanos("onaction", {help: "用户操作", list: ["edit", [ice.VIEW, "横向", "纵向"], "生成图片"],
"edit": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
"edit": function(event, can) { can.onmotion.toggle(can, can._action), can.onmotion.toggle(can, can._status) },
"横向": function(event, can) {
can.onimport._height(can, can._tree[""])
can.sup.view = "横向", can.onmotion.clear(can, can.svg)
@ -98,7 +96,7 @@ Volcanos("onaction", {help: "用户操作", list: ["edit", [ice.VIEW, "横向",
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2v", point: [
can.onimport.draw({}, can, {shape: svg.PATH2V, point: [
{x: x+tree.width/2, y: y+tree.height-can.margin/2},
{x: x+offset+item.width/2, y: y+tree.height+can.margin/2},
], style: {stroke: cli.CYAN}})
@ -115,7 +113,7 @@ Volcanos("onaction", {help: "用户操作", list: ["edit", [ice.VIEW, "横向",
if (tree.hide) { return }
var offset = 0; can.core.List(tree.list, function(item) {
can.onimport.draw({}, can, {shape: "path2h", point: [
can.onimport.draw({}, can, {shape: svg.PATH2H, point: [
{x: x+tree.width+can.margin/8, y: y+tree.height*can.size/2},
{x: x+tree.width+can.margin*2-2*can.margin/8, y: y+offset+item.height*can.size/2}
], style: {stroke: cli.CYAN}})
@ -152,8 +150,8 @@ Volcanos("ondetail", {help: "用户交互", list: [],
}); return }
tree.tags = true
if (msg.Option("split")) {
tree.list = can.onimport._tree(can, msg.Table(), msg.Option("field")||msg.append[0], msg.Option("split"))[""].list||[]
if (msg.Option(lex.SPLIT)) {
tree.list = can.onimport._tree(can, msg.Table(), msg.Option(mdb.FIELD)||msg.append[0], msg.Option(lex.SPLIT))[""].list||[]
can.core.List(tree.list, function(item) { item.last = tree })
} else {
msg.Table(function(item) { tree.list.push({

View File

@ -1,28 +1,28 @@
Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg, list, cb, target) {
can.onmotion.clear(can), can.base.isFunc(cb) && cb(msg)
can.onmotion.hidden(can, can._action)
if (msg.Length() == 0) { return }
if (msg.Option("branch")) { return can.onappend.table(can, msg) }
can.onappend._status(can, ["from", "commit", "total", "max", "date", "text", "add", "del"])
can.Conf(html.HEIGHT, can.Conf(html.HEIGHT)||200)
can.msg = msg, can.data = msg.Table(), can.onimport._sum(can)
can.Action(html.HEIGHT, msg.Option(html.HEIGHT)||"auto")
can.onappend._status(can, ["from", "commit", "total", "max", "date", "text", "add", "del"])
can.data = msg.Table(), can.onimport._sum(can)
can.Action(html.HEIGHT, msg.Option(html.HEIGHT)||ice.AUTO)
can.Action("speed", parseInt(msg.Option("speed")||"100"))
can.onmotion.hidden(can, can._action)
can.require(["/plugin/local/wiki/draw.js", "/plugin/local/wiki/draw/path.js"], function() {
can.page.ClassList.add(can, can._fields, "draw")
can.onimport._show(can, msg), can.onmotion.hidden(can, can.ui.project)
can.onaction[can.Action("view")](event, can)
can.onaction[can.Action(ice.VIEW)](event, can)
})
},
_sum: function(can) {
var begin = "", count = 0, rest = 0, add = 0, del = 0, max = 0
can.max = 0, can.min = 0, can.list = can.core.List(can.data, function(value, index) {
var line = {
date: value[can.msg.append[0]],
text: value[can.msg.append[4]],
add: parseInt(value[can.msg.append[1]]),
del: parseInt(value[can.msg.append[2]]),
date: value[can._msg.append[0]],
text: value[can._msg.append[4]],
add: parseInt(value[can._msg.append[1]]),
del: parseInt(value[can._msg.append[2]]),
}
line.begin = rest
@ -40,19 +40,12 @@ Volcanos("onimport", {help: "导入数据", list: [], _init: function(can, msg,
})
can.Status({"from": begin, "commit": count, "total": add+del, "max": max})
},
layout: function(can) {
can.onaction[can.Action("view")]({}, can)
},
}, [""])
Volcanos("onaction", {help: "组件菜单", list: ["edit", ["view", "趋势图", "柱状图", "数据源"], ["height", "100", "200", "400", "600", "800", "auto"], ["speed", "10", "20", "50", "100"]],
"edit": function(event, can) {
can.onmotion.toggle(can, can._action)
can.onmotion.toggle(can, can._status)
},
Volcanos("onaction", {help: "组件菜单", list: ["edit", [ice.VIEW, "趋势图", "柱状图", "数据源"], ["height", "100", "200", "400", "600", "800", "auto"], ["speed", "10", "20", "50", "100"]],
"edit": function(event, can) { can.onmotion.toggle(can, can._action), can.onmotion.toggle(can, can._status) },
"趋势图": function(event, can) { var height = can.Action(html.HEIGHT)
if (height == "auto") {
height = can.Conf(html.HEIGHT)
}
if (height == ice.AUTO) { height = can.Conf(html.HEIGHT) }
height = parseInt(height)
var space = 10, width = parseInt(can.Conf(html.WIDTH))
@ -65,36 +58,31 @@ Volcanos("onaction", {help: "组件菜单", list: ["edit", ["view", "趋势图",
function scale(y) { return (y - can.min)/(can.max - can.min)*(height-2*space) }
function order(index, x, y) { return {x: space+step*index+x, y: height-space-scale(y)} }
can.core.Next(can.list, function(line, next, index) { can.Status(line, ["date", "text", "add", "del"])
can.core.Next(can.list, function(line, next, index) {
can.onimport.draw({}, can, {
shape: "line", point: [
shape: svg.LINE, point: [
order(index, step/2, line.min), order(index, step/2, line.max),
], style: {
"stroke-width": 1, "stroke": line.begin < line.close? chat.WHITE: chat.BLACK,
},
], style: kit.Dict(html.STROKE_WIDTH, 1, html.STROKE, line.begin < line.close? chat.WHITE: chat.BLACK),
})
can.onimport.draw({}, can, {
shape: "rect", point: [
shape: svg.RECT, point: [
order(index, step/4, line.close), order(index, step/4*3, line.begin),
], style: can.base.Copy({"stroke-width": 1, "rx": 0, "ry": 0}, line.begin < line.close? {
"stroke": chat.WHITE, "fill": chat.WHITE,
}: {
"stroke": chat.BLACK, "fill": chat.BLACK,
}),
], style: can.base.Copy(kit.Dict(html.STROKE_WIDTH, 1, svg.RX, 0, svg.RY, 0), line.begin < line.close?
kit.Dict(html.STROKE, chat.WHITE, html.FILL, chat.WHITE): kit.Dict(html.STROKE, chat.BLACK, html.FILL, chat.BLACK)
),
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
can.core.ItemCB(can.ondetail, function(key, cb) { view[key] = function(event) { cb(event, can, line) } })
},
})
can.Status(line, ["date", "text", "add", "del"])
can.core.Timer(parseInt(can.Action("speed")), next)
})
},
"柱状图": function(event, can) {
var max = {}, min = {}
can.core.List(can.msg.append, function(key, which) {
can.core.List(can._msg.append, function(key, which) {
can.core.List(can.data, function(value, index) {
var v = parseInt(value[key])||0; if (index == 0) {
max[key] = v, min[key] = v
@ -116,20 +104,16 @@ Volcanos("onaction", {help: "组件菜单", list: ["edit", ["view", "趋势图",
function scale(key, y) { return (y - min[key])/(max[key] - min[key])*(height-2*space) }
function order(index, key, x, y) { return {x: space+step*index+x, y: space+scale(key, y)} }
var width = (step-4)/can.msg.append.length
can.core.List(can.msg.append, function(key, which) {
var width = (step-4)/can._msg.append.length
can.core.List(can._msg.append, function(key, which) {
max[key] != min[key] && can.core.Next(can.data, function(line, next, index) {
var y = scale(key, parseFloat(line[key]))
y && can.onimport.draw({}, can, {
shape: "rect", point: [
shape: svg.RECT, point: [
order(index, key, width*which+2, 0), order(index, key, width*which+2+width, y),
], style: {
"stroke-width": 1, "stroke": chat.WHITE, "fill": chat.WHITE, "rx": 0, "ry": 0,
},
], style: kit.Dict(html.STROKE_WIDTH, 1, html.STROKE, cli.WHITE, html.FILL, cli.WHITE, svg.RX, 0, svg.RY, 0),
_init: function(view) {
can.core.ItemCB(can.ondetail, function(key, cb) {
view[key] = function(event) { cb(event, can, line) }
})
can.core.ItemCB(can.ondetail, function(key, cb) { view[key] = function(event) { cb(event, can, line) } })
},
})
@ -139,21 +123,15 @@ Volcanos("onaction", {help: "组件菜单", list: ["edit", ["view", "趋势图",
},
"数据源": function(event, can) {
can.onmotion.clear(can, can.ui.display)
can.onappend.table(can, can.msg, null, can.ui.display)
can.onappend.table(can, can._msg, null, can.ui.display)
can.onmotion.show(can, can.ui.display)
},
height: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
speed: function(event, can) {
can.onaction[can.Action("view")](event, can)
},
height: function(event, can) { can.onaction[can.Action(ice.VIEW)](event, can) },
speed: function(event, can) { can.onaction[can.Action(ice.VIEW)](event, can) },
})
Volcanos("ondetail", {help: "用户交互", list: [],
onmouseenter: function(event, can, line) {
can.Status(line, ["date", "text", "add", "del"])
},
onmouseenter: function(event, can, line) { can.Status(line, ["date", "text", "add", "del"]) },
})
Volcanos("onexport", {help: "导出数据", list: []})

View File

@ -103,6 +103,7 @@ var ssh = {
SCRIPT: "script",
}
var nfs = {
ZML: "zml", IML: "iml",
HTML: "html", CSS: "css", JS: "js", GO: "go", SH: "sh", CSV: "csv", JSON: "json",
PATH: "path", FILE: "file", LINE: "line", SIZE: "size",
DIR: "dir", CAT: "cat", DEFS: "defs", TRASH: "trash",
@ -112,6 +113,9 @@ var nfs = {
var tcp = {
HOST: "host", PORT: "port",
}
var lex = {
SPLIT: "split",
}
var code = {
VIMER: "vimer", INNER: "inner", FAVOR: "favor",
@ -199,8 +203,10 @@ var mall = {
}
var svg = {
G: "g", X: "x", Y: "y", R: "r", RECT: "rect",
G: "g", X: "x", Y: "y", R: "r", RX: "rx", RY: "ry",
LINE: "line", RECT: "rect", TEXT: "text",
M: "M", Q: "Q", T: "T",
PATH2V: "path2v", PATH2H: "path2h",
}
var html = {
FIELDSET: "fieldset", LEGEND: "legend", OPTION: "option", ACTION: "action", OUTPUT: "output", STATUS: "status",