summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Simonis <chs@openerp.com>2011-11-08 17:36:44 +0100
committerChristophe Simonis <chs@openerp.com>2011-11-08 17:36:44 +0100
commit2ea47dc3b2aac73256f361c8ca65de7d8cb40e2c (patch)
tree48ba730f8783b0dcfae4d1230c9f4aeea7a9ff1a
parent1b7125432843d0db93628b04e56065e77d7d14ee (diff)
parent61823d98e9177aefa0e6aecd8750ce2bcb192e9a (diff)
merge upstream
bzr revid: chs@openerp.com-20111108163644-8mlg48lua376lzgg
-rw-r--r--addons/web/__openerp__.py5
-rw-r--r--addons/web/common/openerplib/main.py19
-rw-r--r--addons/web/controllers/main.py86
-rw-r--r--addons/web/po/ar.po699
-rw-r--r--addons/web/po/da.po4
-rw-r--r--addons/web/po/de.po4
-rw-r--r--addons/web/po/es.po4
-rw-r--r--addons/web/po/es_EC.po4
-rw-r--r--addons/web/po/et.po4
-rw-r--r--addons/web/po/fr.po4
-rw-r--r--addons/web/po/gl.po4
-rw-r--r--addons/web/po/it.po4
-rw-r--r--addons/web/po/nl_BE.po4
-rw-r--r--addons/web/po/pl.po687
-rw-r--r--addons/web/po/sl.po4
-rw-r--r--addons/web/static/lib/jquery.MD5/README.md32
-rw-r--r--addons/web/static/lib/jquery.MD5/README.txt32
-rw-r--r--addons/web/static/lib/jquery.MD5/jquery.md5.js269
-rw-r--r--addons/web/static/lib/jquery.MD5/tests/index.html43
-rw-r--r--addons/web/static/lib/jquery.MD5/tests/tests.js57
-rw-r--r--addons/web/static/src/css/base.css53
-rw-r--r--addons/web/static/src/css/data_import.css16
-rw-r--r--addons/web/static/src/js/boot.js2
-rw-r--r--addons/web/static/src/js/chrome.js42
-rw-r--r--addons/web/static/src/js/core.js74
-rw-r--r--addons/web/static/src/js/data.js12
-rw-r--r--addons/web/static/src/js/data_import.js11
-rw-r--r--addons/web/static/src/js/formats.js10
-rw-r--r--addons/web/static/src/js/search.js8
-rw-r--r--addons/web/static/src/js/view_editor.js516
-rw-r--r--addons/web/static/src/js/view_form.js332
-rw-r--r--addons/web/static/src/js/view_list.js57
-rw-r--r--addons/web/static/src/js/view_list_editable.js87
-rw-r--r--addons/web/static/src/js/views.js144
-rw-r--r--addons/web/static/src/xml/base.xml194
-rw-r--r--addons/web/static/test/formats.js2
-rw-r--r--addons/web_calendar/__openerp__.py3
-rw-r--r--addons/web_calendar/po/ar.po22
-rw-r--r--addons/web_calendar/po/da.po4
-rw-r--r--addons/web_calendar/po/de.po4
-rw-r--r--addons/web_calendar/po/es.po4
-rw-r--r--addons/web_calendar/po/es_EC.po4
-rw-r--r--addons/web_calendar/po/et.po4
-rw-r--r--addons/web_calendar/po/fr.po4
-rw-r--r--addons/web_calendar/po/gl.po4
-rw-r--r--addons/web_calendar/po/it.po4
-rw-r--r--addons/web_calendar/po/nl_BE.po4
-rw-r--r--addons/web_calendar/po/sk.po4
-rw-r--r--addons/web_calendar/po/sl.po4
-rw-r--r--addons/web_calendar/static/src/js/calendar.js1
-rw-r--r--addons/web_dashboard/__openerp__.py3
-rw-r--r--addons/web_dashboard/po/ar.po46
-rw-r--r--addons/web_dashboard/po/da.po4
-rw-r--r--addons/web_dashboard/po/de.po4
-rw-r--r--addons/web_dashboard/po/es.po4
-rw-r--r--addons/web_dashboard/po/es_EC.po4
-rw-r--r--addons/web_dashboard/po/et.po4
-rw-r--r--addons/web_dashboard/po/fr.po4
-rw-r--r--addons/web_dashboard/po/gl.po4
-rw-r--r--addons/web_dashboard/po/it.po4
-rw-r--r--addons/web_dashboard/po/nl_BE.po4
-rw-r--r--addons/web_dashboard/po/pl.po46
-rw-r--r--addons/web_dashboard/po/sk.po4
-rw-r--r--addons/web_dashboard/po/sl.po4
-rw-r--r--addons/web_dashboard/static/src/js/dashboard.js3
-rw-r--r--addons/web_dashboard/static/src/xml/web_dashboard.xml2
-rw-r--r--addons/web_default_home/po/ar.po38
-rw-r--r--addons/web_default_home/po/da.po38
-rw-r--r--addons/web_default_home/po/de.po38
-rw-r--r--addons/web_default_home/po/es.po4
-rw-r--r--addons/web_default_home/po/es_EC.po38
-rw-r--r--addons/web_default_home/po/et.po38
-rw-r--r--addons/web_default_home/po/fr.po4
-rw-r--r--addons/web_default_home/po/gl.po4
-rw-r--r--addons/web_default_home/po/it.po38
-rw-r--r--addons/web_default_home/po/nl_BE.po38
-rw-r--r--addons/web_default_home/po/pl.po38
-rw-r--r--addons/web_default_home/po/sk.po38
-rw-r--r--addons/web_default_home/po/sl.po4
-rw-r--r--addons/web_diagram/__openerp__.py3
-rw-r--r--addons/web_diagram/controllers/main.py10
-rw-r--r--addons/web_diagram/po/ar.po54
-rw-r--r--addons/web_diagram/po/da.po4
-rw-r--r--addons/web_diagram/po/de.po4
-rw-r--r--addons/web_diagram/po/es.po4
-rw-r--r--addons/web_diagram/po/es_EC.po4
-rw-r--r--addons/web_diagram/po/et.po4
-rw-r--r--addons/web_diagram/po/gl.po4
-rw-r--r--addons/web_diagram/po/it.po4
-rw-r--r--addons/web_diagram/po/nl_BE.po4
-rw-r--r--addons/web_diagram/po/pl.po54
-rw-r--r--addons/web_diagram/po/sl.po4
-rw-r--r--addons/web_diagram/static/lib/js/dracula_graffle.js13
-rw-r--r--addons/web_diagram/static/lib/js/dracula_graph.js14
-rw-r--r--addons/web_diagram/static/lib/js/raphael-min.js15
-rw-r--r--addons/web_diagram/static/src/css/base_diagram.css10
-rw-r--r--addons/web_diagram/static/src/js/diagram.js87
-rw-r--r--addons/web_diagram/static/src/xml/base_diagram.xml4
-rw-r--r--addons/web_gantt/__openerp__.py3
-rw-r--r--addons/web_gantt/static/src/js/gantt.js89
-rw-r--r--addons/web_graph/__openerp__.py3
-rw-r--r--addons/web_graph/static/src/js/graph.js178
-rw-r--r--addons/web_kanban/__openerp__.py3
-rw-r--r--addons/web_kanban/static/src/css/kanban.css157
-rw-r--r--addons/web_kanban/static/src/js/kanban.js701
-rw-r--r--addons/web_kanban/static/src/xml/web_kanban.xml64
-rw-r--r--addons/web_mobile/po/ar.po66
-rw-r--r--addons/web_mobile/po/da.po4
-rw-r--r--addons/web_mobile/po/de.po4
-rw-r--r--addons/web_mobile/po/es.po4
-rw-r--r--addons/web_mobile/po/es_EC.po4
-rw-r--r--addons/web_mobile/po/et.po4
-rw-r--r--addons/web_mobile/po/fr.po4
-rw-r--r--addons/web_mobile/po/gl.po4
-rw-r--r--addons/web_mobile/po/it.po4
-rw-r--r--addons/web_mobile/po/nl_BE.po4
-rw-r--r--addons/web_mobile/po/pl.po66
-rw-r--r--addons/web_mobile/po/sk.po4
-rw-r--r--addons/web_mobile/po/sl.po4
-rwxr-xr-xopenerp-web (renamed from openerp-web.py)49
-rw-r--r--[-rwxr-xr-x]setup.py172
121 files changed, 4814 insertions, 1182 deletions
diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py
index 1cff3c7956b..50febe0de90 100644
--- a/addons/web/__openerp__.py
+++ b/addons/web/__openerp__.py
@@ -11,6 +11,7 @@
"static/lib/datejs/sugarpak.js",
"static/lib/datejs/extras.js",
"static/lib/jquery/jquery-1.6.2.js",
+ "static/lib/jquery.MD5/jquery.md5.js",
"static/lib/jquery.form/jquery.form.js",
"static/lib/jquery.validate/jquery.validate.js",
"static/lib/jquery.ba-bbq/jquery.ba-bbq.js",
@@ -43,6 +44,7 @@
"static/src/js/view_list.js",
"static/src/js/view_list_editable.js",
"static/src/js/view_tree.js",
+ "static/src/js/view_editor.js"
],
'css' : [
"static/lib/jquery.superfish/css/superfish.css",
@@ -52,4 +54,7 @@
"static/src/css/data_export.css",
"static/src/css/data_import.css",
],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
}
diff --git a/addons/web/common/openerplib/main.py b/addons/web/common/openerplib/main.py
index 5cae9ce4636..773ea020d52 100644
--- a/addons/web/common/openerplib/main.py
+++ b/addons/web/common/openerplib/main.py
@@ -129,6 +129,18 @@ class XmlRPCConnector(Connector):
# TODO should try except and wrap exception into LibException
return getattr(service, method)(*args)
+class XmlRPCSConnector(XmlRPCConnector):
+ """
+ A type of connector that uses the secured XMLRPC protocol.
+ """
+ PROTOCOL = 'xmlrpcs'
+
+ __logger = _getChildLogger(_logger, 'connector.xmlrpcs')
+
+ def __init__(self, hostname, port=8071):
+ super(XmlRPCSConnector, self).__init__(hostname, port)
+ self.url = 'https://%s:%d/xmlrpc' % (self.hostname, self.port)
+
class NetRPC_Exception(Exception):
"""
Exception for NetRPC errors.
@@ -438,6 +450,7 @@ class Model(object):
:return: A list of dictionaries containing all the specified fields.
"""
record_ids = self.search(domain or [], offset, limit or False, order or False, context or {})
+ if not record_ids: return []
records = self.read(record_ids, fields or [], context or {})
return records
@@ -450,15 +463,17 @@ def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
:param port: The number of the port. Defaults to auto.
"""
if port == 'auto':
- port = 8069 if protocol=="xmlrpc" else 8070
+ port = 8069 if protocol=="xmlrpc" else (8070 if protocol == "netrpc" else 8071)
if protocol == "xmlrpc":
return XmlRPCConnector(hostname, port)
+ elif protocol == "xmlrpcs":
+ return XmlRPCSConnector(hostname, port)
elif protocol == "netrpc":
return NetRPCConnector(hostname, port)
elif protocol == "local":
return LocalConnector()
else:
- raise ValueError("You must choose xmlrpc or netrpc or local")
+ raise ValueError("You must choose xmlrpc(s), netrpc or local")
def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
login=None, password=None, user_id=None):
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index 8120141b4f6..74285b1f444 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -24,19 +24,51 @@ openerpweb = web.common.http
# OpenERP Web web Controllers
#----------------------------------------------------------
-def concat_files(file_list):
- """ Concatenate file content
+
+def concat_xml(file_list):
+ """Concatenate xml files
return (concat,timestamp)
concat: concatenation of file content
timestamp: max(os.path.getmtime of file_list)
"""
+ root = None
+ files_timestamp = 0
+ for fname in file_list:
+ ftime = os.path.getmtime(fname)
+ if ftime > files_timestamp:
+ files_timestamp = ftime
+
+ xml = ElementTree.parse(fname).getroot()
+
+ if root is None:
+ root = ElementTree.Element(xml.tag)
+ #elif root.tag != xml.tag:
+ # raise ValueError("Root tags missmatch: %r != %r" % (root.tag, xml.tag))
+
+ for child in xml.getchildren():
+ root.append(child)
+ return ElementTree.tostring(root, 'utf-8'), files_timestamp
+
+
+def concat_files(file_list, reader=None):
+ """ Concatenate file content
+ return (concat,timestamp)
+ concat: concatenation of file content, read by `reader`
+ timestamp: max(os.path.getmtime of file_list)
+ """
+ if reader is None:
+ def reader(f):
+ with open(f) as fp:
+ return fp.read()
+
files_content = []
files_timestamp = 0
for fname in file_list:
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
- files_content.append(open(fname).read())
+
+ files_content.append(reader(fname))
files_concat = "".join(files_content)
return files_concat,files_timestamp
@@ -98,10 +130,42 @@ class WebClient(openerpweb.Controller):
def jslist(self, req, mods=None):
return self.manifest_list(req, mods, 'js')
+ @openerpweb.jsonrequest
+ def qweblist(self, req, mods=None):
+ return self.manifest_list(req, mods, 'qweb')
+
@openerpweb.httprequest
def css(self, req, mods=None):
- files = [f[0] for f in self.manifest_glob(req, mods, 'css')]
- content,timestamp = concat_files(files)
+
+ files = list(self.manifest_glob(req, mods, 'css'))
+ file_map = dict(files)
+
+ rx_import = re.compile(r"""@import\s+('|")(?!'|"|/|https?://)""", re.U)
+ rx_url = re.compile(r"""url\s*\(\s*('|"|)(?!'|"|/|https?://)""", re.U)
+
+
+ def reader(f):
+ """read the a css file and absolutify all relative uris"""
+ with open(f) as fp:
+ data = fp.read()
+
+ web_path = file_map[f]
+ web_dir = os.path.dirname(web_path)
+
+ data = re.sub(
+ rx_import,
+ r"""@import \1%s/""" % (web_dir,),
+ data,
+ )
+
+ data = re.sub(
+ rx_url,
+ r"""url(\1%s/""" % (web_dir,),
+ data,
+ )
+ return data
+
+ content,timestamp = concat_files((f[0] for f in files), reader)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'text/css')])
@@ -113,6 +177,14 @@ class WebClient(openerpweb.Controller):
return req.make_response(content, [('Content-Type', 'application/javascript')])
@openerpweb.httprequest
+ def qweb(self, req, mods=None):
+ files = [f[0] for f in self.manifest_glob(req, mods, 'qweb')]
+ content,timestamp = concat_xml(files)
+ # TODO use timestamp to set Last mofified date and E-tag
+ return req.make_response(content, [('Content-Type', 'text/xml')])
+
+
+ @openerpweb.httprequest
def home(self, req, s_action=None, **kw):
js = "\n ".join('<script type="text/javascript" src="%s"></script>'%i for i in self.manifest_list(req, None, 'js'))
css = "\n ".join('<link rel="stylesheet" href="%s">'%i for i in self.manifest_list(req, None, 'css'))
@@ -451,7 +523,7 @@ def clean_action(req, action, do_not_eval=False):
# values come from the server, we can just eval them
if isinstance(action.get('context'), basestring):
action['context'] = eval( action['context'], eval_ctx ) or {}
-
+
if isinstance(action.get('domain'), basestring):
action['domain'] = eval( action['domain'], eval_ctx ) or []
else:
@@ -1412,7 +1484,7 @@ class Import(View):
return fields
@openerpweb.httprequest
- def detect_data(self, req, csvfile, csvsep, csvdel, csvcode, jsonp):
+ def detect_data(self, req, csvfile, csvsep=',', csvdel='"', csvcode='utf-8', jsonp='callback'):
try:
data = list(csv.reader(
csvfile, quotechar=str(csvdel), delimiter=str(csvsep)))
diff --git a/addons/web/po/ar.po b/addons/web/po/ar.po
new file mode 100644
index 00000000000..0aac2c8aed2
--- /dev/null
+++ b/addons/web/po/ar.po
@@ -0,0 +1,699 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:38+0200\n"
+"PO-Revision-Date: 2011-11-08 05:44+0000\n"
+"Last-Translator: Ahmad Khayyat <Unknown>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-08 06:12+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web/static/src/js/view_form.js:355
+msgid ""
+"Warning, the record has been modified, your changes will be discarded."
+msgstr "تحذير، تم تحرير السجل، تعديلاتك سيتم تجاهلها"
+
+#: addons/web/static/src/js/view_form.js:1659
+msgid "<em>   Search More...</em>"
+msgstr "<em>    مزيداً من البحث...</em>"
+
+#: addons/web/static/src/js/view_form.js:1672
+#, python-format
+msgid "<em>   Create \"<strong>%s</strong>\"</em>"
+msgstr "<em>   إنشاء \"<strong>%s</strong>\"</em>"
+
+#: addons/web/static/src/js/view_form.js:1678
+msgid "<em>   Create and Edit...</em>"
+msgstr "<em>   إنشاء و تحرير...</em>"
+
+#: addons/web/static/src/js/views.js:568
+msgid "You must choose at least one record."
+msgstr "عليك إختيار سجل واحد علي الأقل."
+
+#: addons/web/static/src/js/views.js:569
+msgid "Warning"
+msgstr "تحذير"
+
+#: addons/web/static/src/js/views.js:609
+msgid "Translations"
+msgstr "ترجمات"
+
+#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
+msgid "Save"
+msgstr "حفظ"
+
+#: addons/web/static/src/js/views.js:615
+msgid "Close"
+msgstr "إغلاق"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "x"
+msgstr "x"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#{title}"
+msgstr "#{لقب}"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#{text}"
+msgstr "#{text}"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Powered by"
+msgstr "مدعوم من kifcaliph و"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "openerp.com"
+msgstr "openerp.com"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "."
+msgstr "."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Loading..."
+msgstr "جاري التحميل..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create"
+msgstr "إنشاء"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Drop"
+msgstr "إزالة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Backup"
+msgstr "نسخة إحتياطية"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Restore"
+msgstr "استرجاع"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Password"
+msgstr "كلمة المرور"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Back to Login"
+msgstr "العودة للدخول"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CREATE DATABASE"
+msgstr "إنشاء قاعدة بيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Master password:"
+msgstr "كلمة المرور الرئيسية:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New database name:"
+msgstr "اسم قاعدة البيانات الجديدة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Load Demonstration data:"
+msgstr "تحميل البيانات الوهمية:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Default language:"
+msgstr "اللغة الافتراضية:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Admin password:"
+msgstr "كلمة مرور المشرف العام:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm password:"
+msgstr "تأكيد كلمة المرور:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "DROP DATABASE"
+msgstr "إسقاط قاعدة البيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Database:"
+msgstr "قاعدة البيانات:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Master Password:"
+msgstr "كلمة المرور الرئيسية:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "BACKUP DATABASE"
+msgstr "نسخ إحتياطي لقاعدة البيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "RESTORE DATABASE"
+msgstr "إسترجاع قاعدة بيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "File:"
+msgstr "ملف:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CHANGE MASTER PASSWORD"
+msgstr "تغيير كلمة المرور الرئيسية"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New master password:"
+msgstr "كلمة مرور رئيسية جديدة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm new master password:"
+msgstr "تأكيد كلمة المرور الرئيسية الجديدة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "User:"
+msgstr "مستخدم:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Password:"
+msgstr "كلمة المرور:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Database"
+msgstr "قاعدة بيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Login"
+msgstr "تسجيل الدخول"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Bad username or password"
+msgstr "اسم مستخدم او كلمة مرور خاطئة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"We think that daily job activities can be more intuitive, efficient, "
+"automated, .. and even fun."
+msgstr "نؤمن بأن نشاط العمل اليومي يمكن أن يكون بديهي، فعال، سريع و ممتع"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP's vision to be:"
+msgstr "رؤي برنامج OpenERP هي:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Full featured"
+msgstr "كامل الأوصاف"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Today's enterprise challenges are multiple. We provide one module for each "
+"need."
+msgstr ""
+"تتعدد تحديات المنشآت اليوم، و لذلك نوفر العديد من الوحدات البرمجية لكل "
+"احتياج."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Open Source"
+msgstr "مفتوح المصدر"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"To Build a great product, we rely on the knowledge of thousands of "
+"contributors."
+msgstr "لبناء منتج قوي، نحن نعتمد علي معرفة ألاف المساهمين."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "User Friendly"
+msgstr "سهل الإستخدام"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"In order to be productive, people need clean and easy to use interface."
+msgstr "تتمثل الإنتاجية في حاجة الأفراد إلي إستخدام واجهة سهلة و لائقة."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "("
+msgstr "("
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ")"
+msgstr ")"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "LOGOUT"
+msgstr "تسجيل الخروج"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&laquo;"
+msgstr "&laquo;"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&raquo;"
+msgstr "&raquo;"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "oe_secondary_menu_item"
+msgstr "oe_secondary_menu_item"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "oe_secondary_submenu_item"
+msgstr "oe_secondary_submenu_item"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Hide this tip"
+msgstr "إخفاء هذه الملحوظة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Disable all tips"
+msgstr "تعطيل جميع الإرشادات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "View#"
+msgstr "View#"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Fields"
+msgstr "حقول"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "View labels"
+msgstr "عرض التسميات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Sidebar Relates"
+msgstr "روابط الشريط الجانبي"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Field"
+msgstr "حقل"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ":"
+msgstr ":"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Translate view"
+msgstr "ترجمة العرض"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Translate sidebar"
+msgstr "ترجمة الشريط الجانبي"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Delete"
+msgstr "حذف"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "First"
+msgstr "الأول"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "<"
+msgstr "<"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ">"
+msgstr ">"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Last"
+msgstr "الأخير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "♻"
+msgstr "♻"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & Edit"
+msgstr "حفظ و تحرير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create & Edit"
+msgstr "إنشاء و تحرير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New"
+msgstr "جديد"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Duplicate"
+msgstr "تكرار"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Readonly/Editable"
+msgstr "للقراءة فقط/قابل للتحرير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "<<"
+msgstr ">>"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "0"
+msgstr "0"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "/"
+msgstr "/"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ">>"
+msgstr ">>"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Add"
+msgstr "اضافة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Unhandled widget"
+msgstr "أداة غير معالجة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "?"
+msgstr "؟"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#"
+msgstr "#"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Done"
+msgstr "تم"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Open..."
+msgstr "فتح..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create..."
+msgstr "إنشاء..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Search..."
+msgstr "بحث..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "..."
+msgstr "..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Uploading ..."
+msgstr "جاري التحميل..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Select"
+msgstr "حدّد"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save As"
+msgstr "حفظ كـ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Clear"
+msgstr "إفراغ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Advanced Filter"
+msgstr "مرشحات متقدمة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "-- Filters --"
+msgstr "-- مرشحات --"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "-- Actions --"
+msgstr "-- إجراءات --"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save Filter"
+msgstr "حفظ المرشح"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Manage Filters"
+msgstr "إدارة المرشحات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Filter Name:"
+msgstr "اسم المرشح:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "(Any existing filter with the same name will be replaced)"
+msgstr "(لاحظ أن أي مرشح بنفس الاسم سيتم إستبداله)"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Any of the following conditions must match"
+msgstr "يجب تطابق أي من الشروط التالية"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "All the following conditions must match"
+msgstr "يجب تطابق كل الشروط التالية"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "None of the following conditions must match"
+msgstr "لا يجب تطابق أي من الشروط التالية"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Add condition"
+msgstr "إضافة شرط"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "and"
+msgstr "و"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Cancel"
+msgstr "إلغاء"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & New"
+msgstr "حفظ و جديد"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & Close"
+msgstr "حفظ و إغلاق"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export"
+msgstr "تصدير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"This wizard will export all data that matches the current search criteria to "
+"a CSV file.\n"
+" You can export all data or only the fields that can be "
+"reimported after modification."
+msgstr ""
+"هذا المعالج سيقوم بتصدير كافة البيانات التي تطابق شروط البحث الحالية لملف "
+"CSV.\n"
+" يمكنك تصدير كل البيانات أو الحقول التي يمكن إستيرادها بعد "
+"التعديل."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export Type:"
+msgstr "نوع التصدير:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import Compatible Export"
+msgstr "إستيراد بيانات ملائمة للتصدير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export all Data"
+msgstr "تصدير جميع البيانات"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export Formats"
+msgstr "تنسيقات التصدير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Available fields"
+msgstr "الحقول المتوفرة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Fields to export"
+msgstr "حقول للتصدير"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save fields list"
+msgstr "حفظ قائمة الحقول"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Remove"
+msgstr "إزالة"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Remove All"
+msgstr "إزالة الكل"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Name"
+msgstr "اسم"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&nbsp;"
+msgstr "&nbsp;"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save as:"
+msgstr "حفظ باسم:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Ok"
+msgstr "تم"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Saved exports:"
+msgstr "مُصدرة محفوظة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Old Password:"
+msgstr "كلمة المرور القديمة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New Password:"
+msgstr "كلمة المرور الجديدة:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm Password:"
+msgstr "تأكيد كلمة المرور:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import"
+msgstr "استيراد"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "1. Import a .CSV file"
+msgstr "إستيراد ملف .CSV"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Select a .CSV file to import. If you need a sample of file to import,\n"
+" you should use the export tool with the \"Import Compatible\" option."
+msgstr ""
+"اختر ملف .CSV للإستيراد. إذا كنت بحاجة إلى عينة ملف للاستيراد،\n"
+" يجب عليك إستخدام أداة تصدير مع الخيار \" Compatible\" option."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CSV File:"
+msgstr "ملف CSV :"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "2. Check your file format"
+msgstr "تأكد من إمتداد الملف"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import Options"
+msgstr "خيارات الاستيراد"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Does your file have titles?"
+msgstr "هل لملفك عناوين؟"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Separator:"
+msgstr "فاصل :"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Delimiter:"
+msgstr "محدد:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Encoding:"
+msgstr "ترميز:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "UTF-8"
+msgstr "UTF-8"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Latin 1"
+msgstr "Latin 1"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Lines to skip"
+msgstr "خطوط للتجاهل"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "The import failed due to:"
+msgstr "فشلت عملية الإستيراد للأسباب التالية:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Here is a preview of the file we could not import:"
+msgstr "هذه معاينة لملف لم يتمكن من إستيراده:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP Web"
+msgstr "OpenERP عبر الإنترنت"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Version"
+msgstr "الإصدار"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
+msgstr "جميع حقوق النشر محفوظة لـ © 2011-TODAY OpenERP SA."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP is a trademark of the"
+msgstr "OpenERP هي علامة تجارية لـ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP SA Company"
+msgstr "شركة OpenERP SA"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Licenced under the terms of"
+msgstr "النظام مرخص بشروط"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "GNU Affero General Public License"
+msgstr "GNU Affero General Public License"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "About OpenERP"
+msgstr "عن OpenERP"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP"
+msgstr "OpenERP"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"is a free enterprise-scale software system that is designed to boost\n"
+" productivity and profit through data integration. It connects, "
+"improves and\n"
+" manages business processes in areas such as sales, finance, "
+"supply chain,\n"
+" project management, production, services, CRM, etc..."
+msgstr ""
+"هو نظام حر يناسب المؤسسات و الشركات و تم تصميمه لتعزيز\n"
+" الإنتاجية و الربح من خلال تكامل البيانات. فيمكنك من ربط، و "
+"تحسين، و\n"
+" إدارة العمليات التجارية في إدارات مثل المبيعات، المحاسبة "
+"المالية، المخازن،\n"
+" إدارة المشروعات، الإنتاج و العمليات الصناعية، و القطاع الخدمي، , "
+"إدارة علاقات العملاء..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"The system is platform-independent, and can be installed on Windows, Mac OS "
+"X,\n"
+" and various Linux and other Unix-based distributions. Its "
+"architecture enables\n"
+" new functionality to be rapidly created, modifications to be "
+"made to a\n"
+" production system and migration to a new version to be "
+"straightforward."
+msgstr ""
+"يعمل البرنامج مع العديد من الأنظمة مثل Windows، و Mac OS X، و\n"
+" معظم أنظمة لينكس بالإضافة إلي اليونكس. فلقد تم تصميمه ليتيح "
+"إمكانية\n"
+" إضافة وظائف أخري له بسهولة، و برمجته و تعديله بسرعه ليلائم "
+"الواقع العملي\n"
+" كما أنه يتيح سهولة نقل البيانات من إصدار إلي إصدار."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Depending on your needs, OpenERP is available through a web or application "
+"client."
+msgstr ""
+"حسب إحتياجاتك، نظام OpenERP متاح من خلال تطبيق الويب أو البرنامج المحلي."
diff --git a/addons/web/po/da.po b/addons/web/po/da.po
index cefd844d49a..c0931065d1e 100644
--- a/addons/web/po/da.po
+++ b/addons/web/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
-"X-Generator: Launchpad (build 14124)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/de.po b/addons/web/po/de.po
index 027f34f9866..0a26630321f 100644
--- a/addons/web/po/de.po
+++ b/addons/web/po/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/es.po b/addons/web/po/es.po
index 508b4e62245..9bd7071871b 100644
--- a/addons/web/po/es.po
+++ b/addons/web/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/es_EC.po b/addons/web/po/es_EC.po
index eb2283f6fe5..588408ba979 100644
--- a/addons/web/po/es_EC.po
+++ b/addons/web/po/es_EC.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/et.po b/addons/web/po/et.po
index 75269bf5cda..6b6da84f3a5 100644
--- a/addons/web/po/et.po
+++ b/addons/web/po/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/fr.po b/addons/web/po/fr.po
index a4287a31030..df35344c558 100644
--- a/addons/web/po/fr.po
+++ b/addons/web/po/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/gl.po b/addons/web/po/gl.po
index b43664b9bee..34b2d50085f 100644
--- a/addons/web/po/gl.po
+++ b/addons/web/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/it.po b/addons/web/po/it.po
index fc53244533b..647030fd4ea 100644
--- a/addons/web/po/it.po
+++ b/addons/web/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/nl_BE.po b/addons/web/po/nl_BE.po
index 2a2dccb1712..3d649b59b9d 100644
--- a/addons/web/po/nl_BE.po
+++ b/addons/web/po/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:29+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/po/pl.po b/addons/web/po/pl.po
new file mode 100644
index 00000000000..fde2196a73e
--- /dev/null
+++ b/addons/web/po/pl.po
@@ -0,0 +1,687 @@
+# Polish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:38+0200\n"
+"PO-Revision-Date: 2011-11-04 16:44+0000\n"
+"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web/static/src/js/view_form.js:355
+msgid ""
+"Warning, the record has been modified, your changes will be discarded."
+msgstr "Uwaga, rekord został zmodyfikowany, twoje zmiany zostaną odrzucone."
+
+#: addons/web/static/src/js/view_form.js:1659
+msgid "<em>   Search More...</em>"
+msgstr "<em>   Szukaj dalej...</em>"
+
+#: addons/web/static/src/js/view_form.js:1672
+#, python-format
+msgid "<em>   Create \"<strong>%s</strong>\"</em>"
+msgstr "<em>   Utwórz \"<strong>%s</strong>\"</em>"
+
+#: addons/web/static/src/js/view_form.js:1678
+msgid "<em>   Create and Edit...</em>"
+msgstr "<em>   Utwórz i edytuj...</em>"
+
+#: addons/web/static/src/js/views.js:568
+msgid "You must choose at least one record."
+msgstr "Musisz wybrac co najmniej jeden rekord."
+
+#: addons/web/static/src/js/views.js:569
+msgid "Warning"
+msgstr "Ostrzeżenie"
+
+#: addons/web/static/src/js/views.js:609
+msgid "Translations"
+msgstr "Tłumaczenia"
+
+#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
+msgid "Save"
+msgstr "Zapisz"
+
+#: addons/web/static/src/js/views.js:615
+msgid "Close"
+msgstr "Zamknij"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "x"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#{title}"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#{text}"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Powered by"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "openerp.com"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Loading..."
+msgstr "Wczytywanie..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create"
+msgstr "Utwórz"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Drop"
+msgstr "Usuń bazę danych"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Backup"
+msgstr "Kopia zapasowa bazy danych"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Restore"
+msgstr "Odtwórz bazę danych"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Password"
+msgstr "Hasło"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Back to Login"
+msgstr "Wróć do logowania"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CREATE DATABASE"
+msgstr "UTWÓRZ BAZĘ DANYCH"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Master password:"
+msgstr "Hasło madrzędne:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New database name:"
+msgstr "Nazwa nowej bazy danych:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Load Demonstration data:"
+msgstr "Wczytaj dane demonstracyjne:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Default language:"
+msgstr "Domyślny język:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Admin password:"
+msgstr "Hasło admina:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm password:"
+msgstr "Potwierdź hasło:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "DROP DATABASE"
+msgstr "USUŃ BAZĘ DANYCH"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Database:"
+msgstr "Baza danych:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Master Password:"
+msgstr "Hasło nadrzędne:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "BACKUP DATABASE"
+msgstr "ZAPISZ BAZĘ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "RESTORE DATABASE"
+msgstr "ODTWÓRZ BAZĘ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "File:"
+msgstr "Plik:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CHANGE MASTER PASSWORD"
+msgstr "ZMIEŃ HASŁO NADRZĘDNE"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New master password:"
+msgstr "Nowe hasło nadrzędne:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm new master password:"
+msgstr "Potwierdź nowe hasło nadrzędne:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "User:"
+msgstr "Użytkownik:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Password:"
+msgstr "Hasło:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Database"
+msgstr "Baza danych"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Login"
+msgstr "Login"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Bad username or password"
+msgstr "Niepoprawna nazwa użytkownika lub hasło"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"We think that daily job activities can be more intuitive, efficient, "
+"automated, .. and even fun."
+msgstr ""
+"Sądzimy, że codzienne zadania mogą być bardziej intuicyjne, efektywne, "
+"zautomatyzowan, ... a nawet przyjemne."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP's vision to be:"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Full featured"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Today's enterprise challenges are multiple. We provide one module for each "
+"need."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Open Source"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"To Build a great product, we rely on the knowledge of thousands of "
+"contributors."
+msgstr ""
+"Przy budowie wielkiego produktu polegamy na wiedzy tysięcy społeczników."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "User Friendly"
+msgstr "Przyjazne dla użytkownika"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"In order to be productive, people need clean and easy to use interface."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "("
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ")"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "LOGOUT"
+msgstr "WYLOGUJ"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&laquo;"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&raquo;"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "oe_secondary_menu_item"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "oe_secondary_submenu_item"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Hide this tip"
+msgstr "Ukryj tę wskazówkę"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Disable all tips"
+msgstr "Wyłącz wszystkie wskazówki"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "View#"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Fields"
+msgstr "Pola"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "View labels"
+msgstr "Pokaż etykiety"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Sidebar Relates"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Field"
+msgstr "Pole"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ":"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Translate view"
+msgstr "Przetłumacz widok"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Translate sidebar"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Delete"
+msgstr "Usuń"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "First"
+msgstr "Pierwsze"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "<"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ">"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Last"
+msgstr "Ostatnie"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "♻"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & Edit"
+msgstr "Zapisz i edytuj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create & Edit"
+msgstr "Utwórz i edytuj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New"
+msgstr "Nowy"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Duplicate"
+msgstr "Duplikuj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Readonly/Editable"
+msgstr "Tylko odczyt/Edytowalne"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "<<"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "0"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "/"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ">>"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Add"
+msgstr "Dodaj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Unhandled widget"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "?"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "#"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Done"
+msgstr "Wykonano"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Open..."
+msgstr "Otwórz..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Create..."
+msgstr "Utwórz..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Search..."
+msgstr "Wyszukaj..."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "..."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Uploading ..."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Select"
+msgstr "Wybierz"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save As"
+msgstr "Zapisz jako"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Clear"
+msgstr "Wyczyść"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Advanced Filter"
+msgstr "Zaawansowany filtr"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "-- Filters --"
+msgstr "-- Filtry --"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "-- Actions --"
+msgstr "-- Akcje --"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save Filter"
+msgstr "Zapisz filtr"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Manage Filters"
+msgstr "Zarządzaj filtrami"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Filter Name:"
+msgstr "Nazwa filtra:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "(Any existing filter with the same name will be replaced)"
+msgstr "(Każdy filtr o tej samej nazwie zostanie zamazany)"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Any of the following conditions must match"
+msgstr "Jeden z tych warunków musi być spełniony"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "All the following conditions must match"
+msgstr "Wszystkie warunki muszą być spełnione"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "None of the following conditions must match"
+msgstr "Żadeń z tych warunków nie może być spełniony"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Add condition"
+msgstr "Dodaj warunek"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "and"
+msgstr "i"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Cancel"
+msgstr "Anuluj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & New"
+msgstr "Zapisz i nowy"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save & Close"
+msgstr "Zapisz i zamknij"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export"
+msgstr "Eksportuj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"This wizard will export all data that matches the current search criteria to "
+"a CSV file.\n"
+" You can export all data or only the fields that can be "
+"reimported after modification."
+msgstr ""
+"Ten kreator wyeksportuje wszystkie dane, które spełniają bieżące kryteria "
+"wyszukiwania, do pliku CSV.\n"
+" Możesz eksportować wszystkie dane lub tylko pola, które mają być "
+"importowane po zmianie."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export Type:"
+msgstr "Typ eksportu:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import Compatible Export"
+msgstr "Eksport kompatybilny z importem"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export all Data"
+msgstr "Eksportuj wszystkie dane"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Export Formats"
+msgstr "Format eksportu"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Available fields"
+msgstr "Dostępne pola"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Fields to export"
+msgstr "Pola do eksportu"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save fields list"
+msgstr "Zapisz listę pól"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Remove"
+msgstr "Usuń"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Remove All"
+msgstr "Usuń wszystko"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Name"
+msgstr "Nazwa"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "&nbsp;"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Save as:"
+msgstr "Zapisz jako:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Ok"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Saved exports:"
+msgstr "Zapisane eksporty"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Old Password:"
+msgstr "Poprzednie hasło:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "New Password:"
+msgstr "Nowe hasło:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Confirm Password:"
+msgstr "Potwierdź hasło:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import"
+msgstr "Importuj"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "1. Import a .CSV file"
+msgstr "1. Importuj plik .CSV"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Select a .CSV file to import. If you need a sample of file to import,\n"
+" you should use the export tool with the \"Import Compatible\" option."
+msgstr ""
+"Wybierz plik .CSV do importu. Jeśli chcesz zobaczyć przykład pliku do "
+"importu,\n"
+" powinieneś wyeksportować dane z opcją \"Kompatybilne z importem\"."
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "CSV File:"
+msgstr "Plik CSV:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "2. Check your file format"
+msgstr "2. Sprawdź format pliku"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Import Options"
+msgstr "Opcje importu"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Does your file have titles?"
+msgstr "Czy plik zawiera nazwy pól?"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Separator:"
+msgstr "Separator:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Delimiter:"
+msgstr "Znak dziesiętny:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Encoding:"
+msgstr "Kodowanie:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "UTF-8"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Latin 1"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Lines to skip"
+msgstr "Linie do pominięcia"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "The import failed due to:"
+msgstr "Import się nie udał z powodu:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Here is a preview of the file we could not import:"
+msgstr "Oto podgląd pliku, którego nie można zaimportować:"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP Web"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Version"
+msgstr "Wersja"
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP is a trademark of the"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP SA Company"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "Licenced under the terms of"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "GNU Affero General Public License"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "About OpenERP"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid "OpenERP"
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"is a free enterprise-scale software system that is designed to boost\n"
+" productivity and profit through data integration. It connects, "
+"improves and\n"
+" manages business processes in areas such as sales, finance, "
+"supply chain,\n"
+" project management, production, services, CRM, etc..."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"The system is platform-independent, and can be installed on Windows, Mac OS "
+"X,\n"
+" and various Linux and other Unix-based distributions. Its "
+"architecture enables\n"
+" new functionality to be rapidly created, modifications to be "
+"made to a\n"
+" production system and migration to a new version to be "
+"straightforward."
+msgstr ""
+
+#: addons/web/static/src/xml/base.xml:0
+msgid ""
+"Depending on your needs, OpenERP is available through a web or application "
+"client."
+msgstr ""
diff --git a/addons/web/po/sl.po b/addons/web/po/sl.po
index bc63e7ff313..54349249817 100644
--- a/addons/web/po/sl.po
+++ b/addons/web/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
diff --git a/addons/web/static/lib/jquery.MD5/README.md b/addons/web/static/lib/jquery.MD5/README.md
new file mode 100644
index 00000000000..88778a7a3bf
--- /dev/null
+++ b/addons/web/static/lib/jquery.MD5/README.md
@@ -0,0 +1,32 @@
+# jQuery MD5 Plugin
+
+## Usage
+Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value:
+
+ var md5 = $.md5('value');
+
+Create ([hex](http://en.wikipedia.org/wiki/Hexadecimal)-encoded) [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key:
+
+ var md5 = $.md5('value', 'key');
+
+Create raw [MD5](http://en.wikipedia.org/wiki/MD5) hash of a given string value:
+
+ var md5 = $.md5('value', null, true);
+
+Create raw [HMAC](http://en.wikipedia.org/wiki/HMAC)-MD5 hash of a given string value and key:
+
+ var md5 = $.md5('value', 'key', true);
+
+## Requirements
+None.
+
+If [jQuery](http://jquery.com/) is not available, the md5 function will be added to the global object:
+
+ var md5 = md5('value');
+
+## License
+Released under the [MIT license](http://creativecommons.org/licenses/MIT/).
+
+## Source Code & Download
+* Browse and checkout the [source code](https://github.com/blueimp/jQuery-MD5).
+* [Download](https://github.com/blueimp/jQuery-MD5/archives/master) the project to add the plugin to your website.
diff --git a/addons/web/static/lib/jquery.MD5/README.txt b/addons/web/static/lib/jquery.MD5/README.txt
new file mode 100644
index 00000000000..8a8cbf4db2a
--- /dev/null
+++ b/addons/web/static/lib/jquery.MD5/README.txt
@@ -0,0 +1,32 @@
+jQuery MD5 Plugin
+=================
+
+Usage
+-----
+Create (hex-encoded) MD5 hash of a given string value:
+ var md5 = $.md5('value');
+
+Create (hex-encoded) HMAC-MD5 hash of a given string value and key:
+ var md5 = $.md5('value', 'key');
+
+Create raw MD5 hash of a given string value:
+ var md5 = $.md5('value', null, true);
+
+Create raw HMAC-MD5 hash of a given string value and key:
+ var md5 = $.md5('value', 'key', true);
+
+Requirements
+------------
+None.
+
+If jQuery is not available, the md5 function will be added to the global object:
+ var md5 = md5('value');
+
+License
+-------
+Released under the MIT license:
+http://creativecommons.org/licenses/MIT/
+
+Source Code & Download
+----------------------
+https://github.com/blueimp/jQuery-MD5
diff --git a/addons/web/static/lib/jquery.MD5/jquery.md5.js b/addons/web/static/lib/jquery.MD5/jquery.md5.js
new file mode 100644
index 00000000000..bf9bbe97b55
--- /dev/null
+++ b/addons/web/static/lib/jquery.MD5/jquery.md5.js
@@ -0,0 +1,269 @@
+/*
+ * jQuery MD5 Plugin 1.2.1
+ * https://github.com/blueimp/jQuery-MD5
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://creativecommons.org/licenses/MIT/
+ *
+ * Based on
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*jslint bitwise: true */
+/*global unescape, jQuery */
+
+(function ($) {
+ 'use strict';
+
+ /*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+ function safe_add(x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF),
+ msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+ }
+
+ /*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+ function bit_rol(num, cnt) {
+ return (num << cnt) | (num >>> (32 - cnt));
+ }
+
+ /*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+ function md5_cmn(q, a, b, x, s, t) {
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
+ }
+ function md5_ff(a, b, c, d, x, s, t) {
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+ }
+ function md5_gg(a, b, c, d, x, s, t) {
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+ }
+ function md5_hh(a, b, c, d, x, s, t) {
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+ }
+ function md5_ii(a, b, c, d, x, s, t) {
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+ }
+
+ /*
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ */
+ function binl_md5(x, len) {
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var i, olda, oldb, oldc, oldd,
+ a = 1732584193,
+ b = -271733879,
+ c = -1732584194,
+ d = 271733878;
+
+ for (i = 0; i < x.length; i += 16) {
+ olda = a;
+ oldb = b;
+ oldc = c;
+ oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i], 7, -680876936);
+ d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
+ d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
+ d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
+ d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
+ d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
+ c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
+ d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
+ c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
+ d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
+ c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
+ d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
+ c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
+ d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
+ d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
+ d = md5_hh(d, a, b, c, x[i], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
+ d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i], 6, -198630844);
+ d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
+ d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
+ d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
+ d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return [a, b, c, d];
+ }
+
+ /*
+ * Convert an array of little-endian words to a string
+ */
+ function binl2rstr(input) {
+ var i,
+ output = '';
+ for (i = 0; i < input.length * 32; i += 8) {
+ output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
+ }
+ return output;
+ }
+
+ /*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+ function rstr2binl(input) {
+ var i,
+ output = [];
+ output[(input.length >> 2) - 1] = undefined;
+ for (i = 0; i < output.length; i += 1) {
+ output[i] = 0;
+ }
+ for (i = 0; i < input.length * 8; i += 8) {
+ output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
+ }
+ return output;
+ }
+
+ /*
+ * Calculate the MD5 of a raw string
+ */
+ function rstr_md5(s) {
+ return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
+ }
+
+ /*
+ * Calculate the HMAC-MD5, of a key and some data (raw strings)
+ */
+ function rstr_hmac_md5(key, data) {
+ var i,
+ bkey = rstr2binl(key),
+ ipad = [],
+ opad = [],
+ hash;
+ ipad[15] = opad[15] = undefined;
+ if (bkey.length > 16) {
+ bkey = binl_md5(bkey, key.length * 8);
+ }
+ for (i = 0; i < 16; i += 1) {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+ hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
+ return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
+ }
+
+ /*
+ * Convert a raw string to a hex string
+ */
+ function rstr2hex(input) {
+ var hex_tab = '0123456789abcdef',
+ output = '',
+ x,
+ i;
+ for (i = 0; i < input.length; i += 1) {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F) +
+ hex_tab.charAt(x & 0x0F);
+ }
+ return output;
+ }
+
+ /*
+ * Encode a string as utf-8
+ */
+ function str2rstr_utf8(input) {
+ return unescape(encodeURIComponent(input));
+ }
+
+ /*
+ * Take string arguments and return either raw or hex encoded strings
+ */
+ function raw_md5(s) {
+ return rstr_md5(str2rstr_utf8(s));
+ }
+ function hex_md5(s) {
+ return rstr2hex(raw_md5(s));
+ }
+ function raw_hmac_md5(k, d) {
+ return rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d));
+ }
+ function hex_hmac_md5(k, d) {
+ return rstr2hex(raw_hmac_md5(k, d));
+ }
+
+ $.md5 = function (string, key, raw) {
+ if (!key) {
+ if (!raw) {
+ return hex_md5(string);
+ } else {
+ return raw_md5(string);
+ }
+ }
+ if (!raw) {
+ return hex_hmac_md5(key, string);
+ } else {
+ return raw_hmac_md5(key, string);
+ }
+ };
+
+}(typeof jQuery === 'function' ? jQuery : this)); \ No newline at end of file
diff --git a/addons/web/static/lib/jquery.MD5/tests/index.html b/addons/web/static/lib/jquery.MD5/tests/index.html
new file mode 100644
index 00000000000..27ba8d3607d
--- /dev/null
+++ b/addons/web/static/lib/jquery.MD5/tests/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<!--
+/*
+ * jQuery MD5 Plugin Tests 1.1
+ * https://github.com/blueimp/jQuery-MD5
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://creativecommons.org/licenses/MIT/
+ */
+-->
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>jQuery MD5 Plugin Tests</title>
+<link rel="stylesheet" href="http://code.jquery.com/qunit/git/qunit.css">
+</head>
+<body>
+<h1 id="qunit-header">jQuery MD5 Plugin Tests</h1>
+<h2 id="qunit-banner"></h2>
+<div id="qunit-testrunner-toolbar"></div>
+<h2 id="qunit-userAgent"></h2>
+<ol id="qunit-tests"></ol>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
+<script>
+(function ($) {
+ 'use strict';
+ var nojquery = /nojquery=true/.test(location.search);
+ $('<label><input type="checkbox">nojquery<\/label>').click(function () {
+ location.search = nojquery ? '' : '?nojquery=true';
+ }).appendTo('body').children(':first').attr('checked', nojquery);
+ if (nojquery) {
+ window.jQuery = null;
+ }
+}(window.jQuery));
+</script>
+<script src="../jquery.md5.js"></script>
+<script src="http://code.jquery.com/qunit/git/qunit.js"></script>
+<script src="tests.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/addons/web/static/lib/jquery.MD5/tests/tests.js b/addons/web/static/lib/jquery.MD5/tests/tests.js
new file mode 100644
index 00000000000..ab70f2f991b
--- /dev/null
+++ b/addons/web/static/lib/jquery.MD5/tests/tests.js
@@ -0,0 +1,57 @@
+/*
+ * jQuery MD5 Plugin Tests 1.1
+ * https://github.com/blueimp/jQuery-MD5
+ *
+ * Copyright 2010, Sebastian Tschan
+ * https://blueimp.net
+ *
+ * Licensed under the MIT license:
+ * http://creativecommons.org/licenses/MIT/
+ */
+
+/*global jQuery, module, test, strictEqual */
+
+(function ($) {
+ 'use strict';
+
+ module('Hex-encoded MD5');
+
+ test('Creating hex-encoded MD5 hash of an ASCII value', function () {
+ strictEqual($.md5('value'), '2063c1608d6e0baf80249c42e2be5804');
+ });
+
+ test('Creating hex-encoded MD5 hash of an UTF-8 value', function () {
+ strictEqual($.md5('日本'), '4dbed2e657457884e67137d3514119b3');
+ });
+
+ module('Hex-encoded HMAC-MD5');
+
+ test('Creating hex-encoded HMAC-MD5 hash of an ASCII value and key', function () {
+ strictEqual($.md5('value', 'key'), '01433efd5f16327ea4b31144572c67f6');
+ });
+
+ test('Creating hex-encoded HMAC-MD5 hash of an UTF-8 value and key', function () {
+ strictEqual($.md5('日本', '日本'), 'c78b8c7357926981cc04740bd3e9d015');
+ });
+
+ module('Raw MD5');
+
+ test('Creating raw MD5 hash of an ASCII value', function () {
+ strictEqual($.md5('value', null, true), ' c\xc1`\x8dn\x0b\xaf\x80$\x9cB\xe2\xbeX\x04');
+ });
+
+ test('Creating raw MD5 hash of an UTF-8 value', function () {
+ strictEqual($.md5('日本', null, true), 'M\xbe\xd2\xe6WEx\x84\xe6q7\xd3QA\x19\xb3');
+ });
+
+ module('Raw HMAC-MD5');
+
+ test('Creating raw HMAC-MD5 hash of an ASCII value and key', function () {
+ strictEqual($.md5('value', 'key', true), '\x01C>\xfd_\x162~\xa4\xb3\x11DW,g\xf6');
+ });
+
+ test('Creating raw HMAC-MD5 hash of an UTF-8 value and key', function () {
+ strictEqual($.md5('日本', '日本', true), '\xc7\x8b\x8csW\x92i\x81\xcc\x04t\x0b\xd3\xe9\xd0\x15');
+ });
+
+}(typeof jQuery === 'function' ? jQuery : this)); \ No newline at end of file
diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css
index 6872b921435..94e36d60419 100644
--- a/addons/web/static/src/css/base.css
+++ b/addons/web/static/src/css/base.css
@@ -159,7 +159,7 @@ body.openerp, .openerp textarea, .openerp input, .openerp select, .openerp optio
}
.db_container {
- width: 15%;
+ width: 196px;
background: #666666;
}
@@ -801,13 +801,15 @@ label.error {
-moz-border-radius-topright: 7px;
border-top-right-radius: 7px;
}
-.openerp .oe-listview table.oe-listview-content tfoot td:first-child,
+.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:first-child,
+.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:first-child,
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child th:first-child {
-webkit-border-bottom-left-radius: 7px;
-moz-border-radius-bottomleft: 7px;
border-bottom-left-radius: 7px;
}
-.openerp .oe-listview table.oe-listview-content tfoot td:last-child,
+.openerp .oe-listview table.oe-listview-content tfoot tr:last-child th:last-child,
+.openerp .oe-listview table.oe-listview-content tfoot tr:last-child td:last-child,
.openerp .oe-listview table.oe-listview-content tbody:last-child tr:last-child td:last-child {
-webkit-border-bottom-right-radius: 7px;
-moz-border-radius-bottomright: 7px;
@@ -844,7 +846,7 @@ label.error {
.openerp .oe_frame.oe_forms {
clear: both;
}
-.openerp table.oe_frame td {
+.openerp table.oe_frame {
color: #4c4c4c;
}
.openerp td.oe_form_frame_cell {
@@ -872,7 +874,6 @@ label.error {
}
.openerp .oe_forms label.oe_label, .openerp .oe_forms label.oe_label_help {
- text-align: right;
margin: 3px 0 0 10px;
}
.openerp label.oe_label_help span {
@@ -883,6 +884,18 @@ label.error {
top: -4px;
padding: 0 2px;
}
+.openerp .oe_align_left {
+ text-align: left;
+}
+.openerp .oe_align_right {
+ text-align: right;
+}
+.openerp .oe_align_center {
+ text-align: center;
+}
+.openerp .oe_forms .oe_form_paragraph {
+ margin: 3px 0 0 0;
+}
/* Inputs */
.openerp .oe_forms input[type="text"], .openerp .oe_forms input[type="password"], .openerp .oe_forms select, .openerp .oe_forms textarea {
@@ -1075,7 +1088,7 @@ label.error {
list-style: none;
}
.openerp .oe-view-manager-logs li:before {
- content: '→ ';
+ content: '\2192 ';
}
.openerp .oe-view-manager-logs a {
text-decoration: none;
@@ -1408,3 +1421,31 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after {
border-color: rgba(0,0,0,0);
border-left-color: #B5B9FF;
}
+.openerp .oe_view_editor {
+ border-collapse: collapse;
+ padding: 0;
+ align: left;
+ width: 100%;
+}
+.openerp .oe_view_editor_colum{
+ font-size: 90%;
+ font-weight: normal;
+ padding: 0;
+ border-bottom: 1px solid #CFCCCC;
+}
+.openerp .oe_view_editor_row:hover{
+ background-color: #F3F3F3;
+}
+.openerp .oe_view_editor_tree_grid{
+ text-align: left;
+ white-space: nowrap;
+ border-collapse: collapse;
+ width: 100%;
+}
+.openerp .oe_view_editor_tree_grid a:hover {
+ color: blue;
+}
+.openerp .oe_view_editor_tree_grid a {
+ display: block;
+}
+
diff --git a/addons/web/static/src/css/data_import.css b/addons/web/static/src/css/data_import.css
index 1fb3b22aa45..e5d1c9a910c 100644
--- a/addons/web/static/src/css/data_import.css
+++ b/addons/web/static/src/css/data_import.css
@@ -11,6 +11,22 @@
.openerp .oe_import_grid-row .oe_import_grid-cell {
border-bottom: 1px solid #E3E3E3;
}
+
+.openerp .oe-import-no-result .oe-import-result {
+ display: none;
+}
+.openerp .oe-import fieldset {
+ cursor: pointer;
+}
+.openerp .oe-import fieldset legend:before {
+ content: '\25BC ';
+}
+.openerp .oe-import fieldset.oe-closed legend:before {
+ content: '\25B6 ';
+}
+.openerp .oe-import fieldset.oe-closed table {
+ display: none;
+}
.openerp .separator.horizontal {
font-weight: bold;
border-bottom-width: 1px;
diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js
index f41185be0c6..5fba5f4d8d4 100644
--- a/addons/web/static/src/js/boot.js
+++ b/addons/web/static/src/js/boot.js
@@ -59,7 +59,7 @@ openerp.web = function(instance) {
openerp.web.formats(instance);
openerp.web.chrome(instance);
openerp.web.data(instance);
- var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import"];
+ var files = ["views","search","list","form","list_editable","web_mobile","view_tree","data_export","data_import","view_editor"];
for(var i=0; i<files.length; i++) {
if(openerp.web[files[i]]) {
openerp.web[files[i]](instance);
diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js
index bdb8e23c20b..d85942feead 100644
--- a/addons/web/static/src/js/chrome.js
+++ b/addons/web/static/src/js/chrome.js
@@ -29,11 +29,11 @@ openerp.web.Notification = openerp.web.Widget.extend(/** @lends openerp.web.Not
warn: function(title, text) {
this.$element.notify('create', 'oe_notification_alert', {
title: title,
- text: text,
+ text: text
}, {
- expires: false,
+ expires: false
});
- },
+ }
});
@@ -136,10 +136,10 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
});
-openerp.web.CrashManager = openerp.web.SessionAware.extend({
- init: function(parent) {
- this._super((parent || {}).session);
- this.session.on_rpc_error.add(this.on_rpc_error);
+openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
+ init: function() {
+ this._super();
+ openerp.connection.on_rpc_error.add(this.on_rpc_error);
},
on_rpc_error: function(error) {
this.error = error;
@@ -195,10 +195,20 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
init: function(parent, element_id) {
this._super(parent, element_id);
this.count = 0;
+ this.blocked_ui = false;
this.session.on_rpc_request.add_first(this.on_rpc_event, 1);
this.session.on_rpc_response.add_last(this.on_rpc_event, -1);
},
on_rpc_event : function(increment) {
+ var self = this;
+ if (!this.count && increment === 1) {
+ // Block UI after 3s
+ this.long_running_timer = setTimeout(function () {
+ self.blocked_ui = true;
+ $.blockUI();
+ }, 3000);
+ }
+
this.count += increment;
if (this.count) {
//this.$element.html(QWeb.render("Loading", {}));
@@ -206,6 +216,12 @@ openerp.web.Loading = openerp.web.Widget.extend(/** @lends openerp.web.Loading#
this.$element.show();
this.widget_parent.$element.addClass('loading');
} else {
+ clearTimeout(this.long_running_timer);
+ // Don't unblock if blocked by somebody else
+ if (self.blocked_ui) {
+ this.blocked_ui = false;
+ $.unblockUI();
+ }
this.$element.fadeOut();
this.widget_parent.$element.removeClass('loading');
}
@@ -343,7 +359,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.$option_id.find("form[name=create_db_form]").validate({
submitHandler: function (form) {
var fields = $(form).serializeArray();
- $.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
+ $.blockUI();
self.rpc("/web/database/create", {'fields': fields}, function(result) {
if (result.error) {
$.unblockUI();
@@ -392,7 +408,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
.html(QWeb.render("BackupDB", self))
.find("form[name=backup_db_form]").validate({
submitHandler: function (form) {
- $.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
+ $.blockUI();
self.session.get_file({
form: form,
error: function (body) {
@@ -413,7 +429,7 @@ openerp.web.Database = openerp.web.Widget.extend(/** @lends openerp.web.Database
self.$option_id.find("form[name=restore_db_form]").validate({
submitHandler: function (form) {
- $.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
+ $.blockUI();
$(form).ajaxSubmit({
url: '/web/database/restore',
type: 'POST',
@@ -943,17 +959,15 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this._super(null, element_id);
openerp.webclient = this;
- QWeb.add_template("/web/static/src/xml/base.xml");
var params = {};
if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.$element.addClass("kitten-mode-activated");
}
this.$element.html(QWeb.render("Interface", params));
- this.notification = new openerp.web.Notification();
- this.session = new openerp.web.Session();
+ this.notification = new openerp.web.Notification(this);
this.loading = new openerp.web.Loading(this,"oe_loading");
- this.crashmanager = new openerp.web.CrashManager(this);
+ this.crashmanager = new openerp.web.CrashManager();
this.header = new openerp.web.Header(this);
this.login = new openerp.web.Login(this);
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index 1b6a6302f72..951e6e2b01f 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -237,8 +237,8 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
* registry was created.
*
* An object path is simply a dotted name from the openerp root to the
- * object pointed to (e.g. ``"openerp.web.Session"`` for an OpenERP
- * session object).
+ * object pointed to (e.g. ``"openerp.web.Connection"`` for an OpenERP
+ * connection object).
*
* @constructs openerp.web.Registry
* @param {Object} mapping a mapping of keys to object-paths
@@ -338,9 +338,9 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.Ca
}
});
-openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Session# */{
+openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{
/**
- * @constructs openerp.web.Session
+ * @constructs openerp.web.Connection
* @extends openerp.web.CallbackEnabled
*
* @param {String} [server] JSON-RPC endpoint hostname
@@ -364,7 +364,9 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
// TODO: session should have an optional name indicating that they'll
// be saved to (and revived from) cookies
this.name = 'session';
+ this.do_load_qweb(['/web/webclient/qweb']);
},
+
start: function() {
this.session_restore();
},
@@ -484,9 +486,11 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
self.user_context = result.context;
self.db = result.db;
self.session_save();
+ self.on_session_valid();
return true;
}).then(success_callback);
},
+ login: function() { this.session_login.apply(this, arguments); },
/**
* Reloads uid and session_id from local storage, if they exist
*/
@@ -574,6 +578,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) {
self.do_load_js(file_list.concat(files));
});
+ self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb);
openerp._modules_loaded = true;
});
});
@@ -607,6 +612,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
this.on_modules_loaded();
}
},
+ do_load_qweb: function(files) {
+ var self = this;
+ _.each(files, function(file) {
+ openerp.web.qweb.add_template(file);
+ });
+ },
on_modules_loaded: function() {
for(var j=0; j<this.module_list.length; j++) {
var mod = this.module_list[j];
@@ -713,36 +724,6 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
}
});
-openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.SessionAware# */{
- /**
- * Utility class that any class is allowed to extend to easy common manipulations.
- *
- * It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a
- * logging facility.
- *
- * @constructs openerp.web.SessionAware
- * @extends openerp.web.CallbackEnabled
- *
- * @param {openerp.web.Session} session
- */
- init: function(session) {
- this._super();
- this.session = session;
- },
- /**
- * Performs a JSON-RPC call
- *
- * @param {String} url endpoint url
- * @param {Object} data RPC parameters
- * @param {Function} success RPC call success callback
- * @param {Function} error RPC call error callback
- * @returns {jQuery.Deferred} deferred object for the RPC call
- */
- rpc: function(url, data, success, error) {
- return this.session.rpc(url, data, success, error);
- }
-});
-
/**
* Base class for all visual components. Provides a lot of functionalities helpful
* for the management of a part of the DOM.
@@ -753,8 +734,6 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
* destroyed too).
* - Insertion in DOM.
*
- * Widget also extends SessionAware for ease of use.
- *
* Guide to create implementations of the Widget class:
* ==============================================
*
@@ -795,7 +774,7 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
*
* That will kill the widget in a clean way and erase its content from the dom.
*/
-openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widget# */{
+openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.Widget# */{
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
@@ -814,7 +793,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* Construct the widget and set its parent if a parent is given.
*
* @constructs openerp.web.Widget
- * @extends openerp.web.SessionAware
+ * @extends openerp.web.CallbackEnabled
*
* @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling stop(), the current instance will be
@@ -825,7 +804,8 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* for new components this argument should not be provided any more.
*/
init: function(parent, /** @deprecated */ element_id) {
- this._super((parent || {}).session);
+ this._super();
+ this.session = openerp.connection;
// if given an element_id, try to get the associated DOM element and save
// a reference in this.$element. Else just generate a unique identifier.
this.element_id = element_id;
@@ -964,7 +944,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
rpc: function(url, data, success, error) {
var def = $.Deferred().then(success, error);
var self = this;
- this._super(url, data). then(function() {
+ openerp.connection.rpc(url, data). then(function() {
if (!self.widget_is_stopped)
def.resolve.apply(def, arguments);
}, function() {
@@ -1040,12 +1020,21 @@ openerp.web.TranslationDataBase = openerp.web.Class.extend(/** @lends openerp.we
}
});
+if ($.blockUI) {
+ $.blockUI.defaults.baseZ = 1100;
+ $.blockUI.defaults.message = '<img src="/web/static/src/img/throbber2.gif">';
+}
+
+/** Configure default qweb */
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
openerp.web.qweb = new QWeb2.Engine();
openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
+openerp.web.qweb.default_dict = {
+ '_' : _
+}
openerp.web.qweb.format_text_node = function(s) {
// Note that 'this' is the Qweb Node of the text
- var translation = this.node.parentElement.attributes['t-translation'];
+ var translation = this.node.parentNode.attributes['t-translation'];
if (translation && translation.value === 'off') {
return s;
}
@@ -1057,6 +1046,9 @@ openerp.web.qweb.format_text_node = function(s) {
return tr === ts ? s : tr;
}
+/** Setup default connection */
+openerp.connection = new openerp.web.Connection();
+
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:
diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js
index 069506586ad..f4509c82a81 100644
--- a/addons/web/static/src/js/data.js
+++ b/addons/web/static/src/js/data.js
@@ -32,7 +32,7 @@ openerp.web.DataGroup = openerp.web.Widget.extend( /** @lends openerp.web.DataG
* @constructs openerp.web.DataGroup
* @extends openerp.web.Widget
*
- * @param {openerp.web.Session} session Current OpenERP session
+ * @param {openerp.web.Widget} parent widget
* @param {String} model name of the model managed by this DataGroup
* @param {Array} domain search domain for this DataGroup
* @param {Object} context context of the DataGroup's searches
@@ -785,11 +785,15 @@ openerp.web.ProxyDataSet = openerp.web.DataSetSearch.extend({
on_unlink: function(ids) {}
});
-openerp.web.Model = openerp.web.SessionAware.extend({
- init: function(session, model_name) {
- this._super(session);
+openerp.web.Model = openerp.web.CallbackEnabled.extend({
+ init: function(_, model_name) {
+ this._super();
this.model_name = model_name;
},
+ rpc: function() {
+ var c = openerp.connection;
+ return c.rpc.apply(c, arguments);
+ },
get_func: function(method_name) {
var self = this;
return function() {
diff --git a/addons/web/static/src/js/data_import.js b/addons/web/static/src/js/data_import.js
index 711e790dfaa..355c6c1b493 100644
--- a/addons/web/static/src/js/data_import.js
+++ b/addons/web/static/src/js/data_import.js
@@ -80,8 +80,8 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
this.toggle_import_button(false);
this.$element.find('#csvfile').change(this.on_autodetect_data);
this.$element.find('fieldset').change(this.on_autodetect_data);
- this.$element.find('fieldset legend').click(function() {
- $(this).next().toggle();
+ this.$element.delegate('fieldset legend', 'click', function() {
+ $(this).parent().toggleClass('oe-closed');
});
this.ready.push(new openerp.web.DataSet(this, this.model).call(
'fields_get', [], function (fields) {
@@ -194,9 +194,11 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
: with_headers ? results.records.slice(1)
: results.records
}));
+ this.$element.find('fieldset').addClass('oe-closed');
} else if (results['error']) {
result_node.append(QWeb.render('ImportView.error', {
'error': results['error']}));
+ this.$element.find('fieldset').removeClass('oe-closed');
} else if (results['success']) {
if (this.widget_parent.widget_parent.active_view == "list") {
this.widget_parent.reload_content();
@@ -204,6 +206,11 @@ openerp.web.DataImport = openerp.web.Dialog.extend({
this.stop();
return;
}
+ this.$element.find('form').removeClass('oe-import-no-result');
+
+ this.$element.delegate('.oe-m2o-drop-down-button', 'click', function () {
+ $(this).prev('input').focus();
+ });
var self = this;
this.ready.then(function () {
diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js
index 3ab972f7a86..ca540844b7f 100644
--- a/addons/web/static/src/js/formats.js
+++ b/addons/web/static/src/js/formats.js
@@ -27,14 +27,8 @@ openerp.web.format_value = function (value, descriptor, value_if_empty) {
return _.sprintf('%d', value);
case 'float':
var precision = descriptor.digits ? descriptor.digits[1] : 2;
- var int_part = Math.floor(value);
- var dec_part = _.sprintf(
- '%.' + precision + 'f',
- Math.abs(value) % 1).substring(2);
- return _.sprintf('%d%s%s',
- int_part,
- openerp.web._t.database.parameters.decimal_point,
- dec_part);
+ return _.sprintf('%.' + precision + 'f', value)
+ .replace('.', openerp.web._t.database.parameters.decimal_point);
case 'float_time':
return _.sprintf("%02d:%02d",
Math.floor(value),
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index c7aa1e3cfe3..18e035a40b8 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -63,6 +63,7 @@ openerp.web.SearchView = openerp.web.Widget.extend(/** @lends openerp.web.Search
rows.push(row);
var filters = [];
_.each(items, function (item) {
+ if (item.attrs.invisible === '1') { return; }
if (filters.length && item.tag !== 'filter') {
row.push(
new openerp.web.search.FilterGroup(
@@ -432,6 +433,7 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
* @param view the ancestor view of this widget
*/
init: function (view) {
+ this._super(view);
this.view = view;
},
/**
@@ -472,10 +474,8 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
this._super();
},
render: function (defaults) {
- return QWeb.render(
- this.template, _.extend(this, {
- defaults: defaults
- }));
+ // FIXME
+ return this._super(_.extend(this, {defaults: defaults}));
}
});
openerp.web.search.add_expand_listener = function($root) {
diff --git a/addons/web/static/src/js/view_editor.js b/addons/web/static/src/js/view_editor.js
new file mode 100644
index 00000000000..71cda6fcc47
--- /dev/null
+++ b/addons/web/static/src/js/view_editor.js
@@ -0,0 +1,516 @@
+openerp.web.view_editor = function(openerp) {
+var QWeb = openerp.web.qweb;
+openerp.web.ViewEditor = openerp.web.Widget.extend({
+ init: function(parent, element_id, dataset, view, options) {
+ this._super(parent);
+ this.element_id = element_id
+ this.parent = parent
+ this.dataset = dataset;
+ this.model = dataset.model;
+ this.xml_id = 0;
+ },
+ start: function() {
+ this.init_view_editor();
+ },
+ init_view_editor: function() {
+ var self = this;
+ var action = {
+ name:'ViewEditor',
+ context:this.session.user_context,
+ domain: [["model", "=", this.dataset.model]],
+ res_model : 'ir.ui.view',
+ views : [[false, 'list']],
+ type: 'ir.actions.act_window',
+ target: "current",
+ limit : 80,
+ auto_search : true,
+ flags: {
+ sidebar: false,
+ deletable: false,
+ views_switcher: false,
+ action_buttons:false,
+ search_view:false,
+ pager:false,
+ radio: true
+ },
+ };
+ this.view_edit_dialog = new openerp.web.Dialog(this, {
+ modal: true,
+ title: 'ViewEditor',
+ width: 750,
+ height: 500,
+ buttons: {
+ "Create": function(){
+ //to do
+ },
+ "Edit": function(){
+ self.xml_id=0;
+ self.get_data();
+ },
+ "Close": function(){
+ self.view_edit_dialog.close();
+ }
+ },
+ });
+ this.view_edit_dialog.start().open();
+ var action_manager = new openerp.web.ActionManager(this);
+ action_manager.appendTo(this.view_edit_dialog);
+ action_manager.do_action(action);
+ },
+ check_attr: function(xml, tag, level) {
+ var obj = {'child_id': [], 'id': this.xml_id++, 'level': level+1, 'att_list': [], 'name': ""};
+ var render_name = "<" + tag;
+ obj.att_list.push(tag);
+ $(xml).each(function() {
+ _.each(this.attributes, function(attrs){
+ if (tag != 'button') {
+ if (attrs.nodeName == "string" || attrs.nodeName == "name" || attrs.nodeName == "index") {
+ render_name += ' ' + attrs.nodeName + '=' + '"' + attrs.nodeValue + '"' ;
+ }
+ } else {
+ if (attrs.nodeName == "name") {
+ render_name += ' ' + attrs.nodeName + '=' + '"' + attrs.nodeValue + '"';
+ }
+ }
+ obj.att_list.push( [attrs.nodeName,attrs.nodeValue] );
+ });
+ render_name+= ">";
+ });
+ obj.name = render_name;
+ return obj;
+ },
+ save_object: function(val, parent_list, child_obj_list) {
+ var self = this;
+ var check_id = parent_list[0];
+ var p_list = parent_list.slice(1);
+ if (val.child_id.length != 0) {
+ _.each(val.child_id, function(val, key) {
+ if (val.id == check_id) {
+ if (p_list.length!=0) {
+ self.save_object(val, p_list, child_obj_list);
+ } else {
+ val.child_id = child_obj_list;
+ return false;
+ }
+ }
+ });
+ } else {
+ val.child_id = child_obj_list;
+ }
+ },
+ xml_node_create: function(xml, root, parent_list, parent_id, main_object){
+ var self = this;
+ var child_obj_list = [];
+ var children_list = $(xml).filter(root).children();
+ var parents = $(children_list[0]).parents().get();
+ _.each(children_list, function (child_node) {
+ child_obj_list.push(self.check_attr(child_node,child_node.tagName.toLowerCase(),parents.length));
+ });
+ if (children_list.length != 0) {
+ if (parents.length <= parent_list.length) {
+ parent_list.splice(parents.length - 1);
+ }
+ parent_list.push(parent_id);
+ self.save_object(main_object[0], parent_list.slice(1), child_obj_list);
+ }
+ for (var i = 0; i < children_list.length; i++) {
+ self.xml_node_create
+ (children_list[i], children_list[i].tagName.toLowerCase(),
+ parent_list, child_obj_list[i].id, main_object);
+ }
+ return main_object;
+ },
+ parse_xml: function(arch, view_id) {
+ var root = $(arch).filter(":first")[0];
+ var tag = root.tagName.toLowerCase();
+ var obj ={'child_id':[],'id':this.xml_id++,'level':0,'att_list':[],'name':"<view view_id='"+view_id+"'>"};
+ var root_object = this.check_attr(root,tag,0);
+ obj.child_id = this.xml_node_create(arch, tag, [], this.xml_id-1, [root_object], [])
+ return [obj];
+ },
+ get_data: function() {
+ var self = this;
+ var view_arch_list = [];
+ self.main_view_id =((this.view_edit_dialog.$element.find("input[name='radiogroup']:checked").parent()).parent()).attr('data-id');
+ var ve_dataset = new openerp.web.DataSet(this, 'ir.ui.view');
+ ve_dataset.read_ids([parseInt(self.main_view_id)], ['arch', 'type'], function (arch) {
+ one_object = self.parse_xml(arch[0].arch,self.main_view_id);
+ self.main_view_type = arch[0].type
+ view_arch_list.push({"view_id" : self.main_view_id, "arch" : arch[0].arch});
+ dataset = new openerp.web.DataSetSearch(self, 'ir.ui.view', null, null);
+ dataset.read_slice([], {domain : [['inherit_id','=', parseInt(self.main_view_id)]]}, function (result) {
+ _.each(result, function(res) {
+ view_arch_list.push({"view_id":res.id,"arch":res.arch});
+ self.inherit_view(one_object, res);
+ });
+ return self.edit_view({"main_object": one_object,
+ "parent_child_id": self.parent_child_list(one_object, []),
+ "arch": view_arch_list});
+ });
+ });
+ },
+ parent_child_list : function(one_object, p_list) {
+ var self = this;
+ _.each(one_object , function(element){
+ if(element.child_id.length != 0){
+ p_list.push({"key":element.id,"value":_.pluck(element.child_id, 'id')});
+ self.parent_child_list(element.child_id, p_list);
+ }
+ });
+ return p_list;
+ },
+ inherit_view : function(one_object, result) {
+ var self = this;
+ var root = $(result.arch).filter('*');
+ var xml_list = [];
+ if (root[0].tagName.toLowerCase() == "data") {
+ xml_list = $(root[0]).children();
+ } else {
+ xml_list.push(root[0]);
+ }
+ _.each(xml_list , function(xml){
+ var parent_id;
+ var check_list = [];
+ var xpath_object = self.parse_xml(xml,result.id);
+ if (xml.tagName.toLowerCase() == "xpath" ) {
+ var part_expr = _.without($(xml).attr('expr').split("/"),"");
+ _.each(part_expr,function(part){
+ check_list.push(_.without($.trim(part.replace(/[^a-zA-Z 0-9 _]+/g,'!')).split("!"),""));
+ });
+ } else {
+ var temp = [];
+ _.each(xpath_object[0].child_id[0].att_list, function(list){
+ if(!_.include(list, "position")){
+ temp.push(list);
+ }
+ });
+ check_list = [_.flatten(temp)];
+ }
+ self.full_path_search(check_list ,one_object ,xpath_object);
+ });
+ },
+ full_path_search: function(check_list ,val ,xpath_object) {
+ var self = this;
+ if(xpath_object.length!=0){
+ var check = check_list[0];
+ var obj;
+ switch (check.length) {
+ case 2:
+ if(parseInt(check[1])){
+ var list_1 = _.select(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ obj = val[_.indexOf(val,list_1[parseInt(check[1])-1])];
+ } else {
+ obj = _.detect(val, function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ }
+ break;
+ case 3:
+ obj = _.detect(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ check = _.uniq(check);
+ var insert = _.intersection(main_list,check);
+ if(insert.length == check.length ){return element;}
+ });
+ break;
+ case 1:
+ var list_1 = _.select(val,function(element){
+ var main_list = _.flatten(element.att_list);
+ return _.include(main_list, check[0]);
+ });
+ if(list_1.length != 0){
+ (check_list.length == 1)? obj = list_1[0] : check_list.shift();
+ }
+ break;
+ }
+ if(obj) {
+ check_list.shift();
+ if (check_list.length !=0){
+ self.full_path_search(check_list ,obj.child_id ,xpath_object);
+ } else {
+ var level = obj.level+1;
+ self.increase_level(xpath_object[0], level)
+ obj.child_id.push(xpath_object[0]);
+ xpath_object.pop();
+ return;
+ }
+ }
+ else {
+ _.each(val,function(element){
+ self.full_path_search(check_list ,element.child_id ,xpath_object);
+ });
+ }
+ }
+ },
+ increase_level: function(val, level) {
+ var self = this;
+ val.level = level;
+ _.each(val.child_id, function(val, key) {
+ self.increase_level(val, level + 1);
+ });
+ },
+ edit_view: function(one_object) {
+ var self = this;
+ this.edit_xml_dialog = new openerp.web.Dialog(this,{
+ modal: true,
+ title: 'View Editor',
+ width: 750,
+ height: 500,
+ buttons: {
+ "Inherited View": function(){
+ //todo
+ },
+ "Preview": function(){
+ var action = {
+ context:self.session.user_context,
+ res_model : self.model,
+ views : [[self.main_view_id, self.main_view_type]],
+ type: 'ir.actions.act_window',
+ target: "new",
+ flags: {
+ sidebar: false,
+ views_switcher: false,
+ action_buttons:false,
+ search_view:false,
+ pager:false,
+ },
+ };
+ var action_manager = new openerp.web.ActionManager(self);
+ action_manager.do_action(action);
+ },
+ "Close": function(){
+ self.edit_xml_dialog.close();
+ }
+ }
+ });
+ this.edit_xml_dialog.start().open();
+ this.edit_xml_dialog.$element.html(QWeb.render('view_editor', {
+ 'data': one_object['main_object'],
+ }));
+ this.edit_xml_dialog.$element.find("tr[id^='viewedit-']").click(function() {
+ self.edit_xml_dialog.$element.find("tr[id^='viewedit-']").removeClass('ui-selected');
+ $(this).addClass('ui-selected');
+ });
+ this.edit_xml_dialog.$element.find("img[id^='parentimg-']").click(function() {
+ if ($(this).attr('src') == '/web/static/src/img/collapse.gif') {
+ $(this).attr('src', '/web/static/src/img/expand.gif');
+ self.on_expand(this);
+ } else {
+ $(this).attr('src', '/web/static/src/img/collapse.gif');
+ var id = this.id.split('-')[1];
+ self.on_collapse(this,one_object['parent_child_id'], one_object['main_object']);
+ }
+ });
+ this.edit_xml_dialog.$element.find("img[id^='side-']").click(function() {
+ var side = $(this).closest("tr[id^='viewedit-']")
+ var id_tr = (side.attr('id')).split('-')[1];
+ var img = side.find("img[id='parentimg-"+id_tr+"']").attr('src'); ;
+ var level = parseInt(side.attr('level'));
+ var list_shift =[];
+ var last_tr;
+ var cur_tr = side;
+ list_shift.push(side);
+ var next_tr;
+ var ls = side;
+ var view_id;
+ var view_xml_id;
+ while(1){
+ ls = ls.prev();
+ if((self.edit_xml_dialog.$element.find(ls).find('a').text()).search("view_id") != -1
+ && parseInt(ls.attr('level')) < level){
+ view_id = parseInt(($(ls).find('a').text()).replace(/[^0-9]+/g,''));
+ view_xml_id = (ls.attr('id')).split('-')[1];
+ break;
+ }
+ }
+ switch (this.id) {
+ case "side-add":
+ break;
+ case "side-remove":
+ break;
+ case "side-edit":
+ break;
+ case "side-up":
+ while (1) {
+ var prev_tr = cur_tr.prev();
+ if(level >= parseInt(prev_tr.attr('level')) || prev_tr.length == 0) {
+ last_tr = prev_tr;
+ break;
+ }
+ cur_tr = prev_tr;
+ }
+ if (img) {
+ while (1) {
+ next_tr = side.next();
+ if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
+ break;
+ } else {
+ list_shift.push(next_tr);
+ side = next_tr;
+ }
+ }
+ }
+ if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level &&
+ (self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") == -1) {
+ _.each(list_shift, function(rec) {
+ $(last_tr).before(rec);
+ });
+ self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "up");
+ }
+ break;
+ case "side-down":
+ if (img) {
+ while (1) {
+ next_tr = cur_tr.next();
+ if ( parseInt(next_tr.attr('level')) <= level || next_tr.length == 0) {
+ last_tr = next_tr;
+ break;
+ } else {
+ list_shift.push(next_tr);
+ cur_tr = next_tr;
+ }
+ }
+ }
+ else {
+ last_tr = cur_tr.next();
+ }
+ if((self.edit_xml_dialog.$element.find(last_tr).find('a').text()).search("view_id") != -1){
+ return;
+ }
+ if (last_tr.length != 0 && parseInt(last_tr.attr('level')) == level) {
+ var last_tr_id = (last_tr.attr('id')).split('-')[1];
+ img = last_tr.find("img[id='parentimg-" + last_tr_id + "']").attr('src');
+ if (img) {
+ self.edit_xml_dialog.$element.find("img[id='parentimg-" + last_tr_id + "']").
+ attr('src', '/web/static/src/img/expand.gif');
+ while (1) {
+ var next_tr = last_tr.next();
+ if (next_tr.attr('level') <= level || next_tr.length == 0) break;
+ next_tr.hide();
+ last_tr = next_tr;
+ }
+ }
+ list_shift.reverse();
+ _.each(list_shift, function(rec) {
+ $(last_tr).after(rec);
+ });
+ self.save_move_arch(one_object, view_id, view_xml_id, id_tr, level, "down");
+ }
+ break;
+ }
+ });
+ },
+ save_move_arch: function(one_object, view_id, view_xml_id, id_tr, level, move_direct){
+ var self = this;
+ var arch = _.detect(one_object['arch'],function(element){
+ return element.view_id == view_id;
+ });
+ var obj = self.get_view_object(view_xml_id, one_object['main_object'], []);
+ if(($(arch.arch).filter("data")).length != 0 && view_xml_id != 0){
+ var check_list = _.flatten(obj[0].child_id[0].att_list);
+ arch.arch = _.detect($(arch.arch).children(), function(xml_child){
+ var temp_obj = self.check_attr(xml_child, xml_child.tagName.toLowerCase());
+ var main_list = _.flatten(temp_obj.att_list);
+ check_list = _.uniq(check_list);
+ var insert = _.intersection(main_list,check_list);
+ if(insert.length == check_list.length ){return xml_child;}
+ });
+ }
+ return self.get_node(arch.arch, obj[0].child_id[0], parseInt(id_tr), [], parseInt(level),
+ parseInt(view_id), arch, move_direct);
+ },
+
+ get_view_object: function(view_xml_id, one_object,result){
+ var self = this;
+ if(result.length==0){
+ var check = _.detect(one_object , function(obj){
+ return view_xml_id==obj.id;
+ });
+ if(check){result.push(check);};
+ _.each(one_object, function(obj){
+ self.get_view_object(view_xml_id, obj.child_id, result);
+ });
+ }
+ return result;
+ },
+ get_node: function(arch1, obj, id, child_list, level, view_id, arch, move_direct){
+ var self = this;
+ var children_list = $(arch1).children();
+ var list_obj_xml = _.zip(children_list,obj.child_id);
+ if (id) {
+ if (obj.id == id) {
+ var id;
+ var parent = $(arch1).parents();
+ var index = _.indexOf(child_list, obj)
+ var re_insert_obj = child_list.splice(index, 1);
+ if (move_direct == "down") {
+ var next = $(arch1).next();
+ $(next).after(arch1);
+ child_list.splice(index+1, 0, re_insert_obj[0]);
+ } else {
+ var prev = $(arch1).prev();
+ $(prev).before(arch1);
+ child_list.splice(index-1, 0, re_insert_obj[0]);
+ }
+ parent = parent[parent.length-1];
+ var convert_to_utf = self.xml2Str(parent);
+ if (convert_to_utf) {
+ convert_to_utf = convert_to_utf.replace('xmlns="http://www.w3.org/1999/xhtml"', "");
+ convert_to_utf = '<?xml version="1.0"?>' + convert_to_utf;
+ arch.arch = convert_to_utf;
+ dataset = new openerp.web.DataSet(this, 'ir.ui.view');
+ dataset.write(parseInt(view_id),{"arch":convert_to_utf}, function(r) {
+ });
+ }
+ }
+ if (obj.level <= level) {
+ _.each(list_obj_xml, function(child_node) {
+ self.get_node(child_node[0], child_node[1], id, obj.child_id, level, view_id, arch, move_direct);
+ });
+ }
+ }
+ },
+ xml2Str: function(xmlNode) {
+ try {
+ return (new XMLSerializer()).serializeToString(xmlNode);
+ }
+ catch (e) {
+ try {
+ return xmlNode.xml;
+ }
+ catch (e) {
+ return false;
+ }
+ }
+
+ },
+ on_expand: function(expand_img){
+ var level = parseInt($(expand_img).closest("tr[id^='viewedit-']").attr('level'));
+ var cur_tr = $(expand_img).closest("tr[id^='viewedit-']");
+ while (1) {
+ var nxt_tr = cur_tr.next();
+ if (parseInt(nxt_tr.attr('level')) > level){
+ cur_tr = nxt_tr;
+ nxt_tr.hide();
+ } else return nxt_tr;
+ }
+ },
+ on_collapse: function(collapse_img, parent_child_id, id, main_object) {
+ var self = this;
+ var id = collapse_img.id.split('-')[1];
+ var datas = _.detect(parent_child_id,function(res) {
+ return res.key == id;
+ });
+ _.each(datas.value, function(rec) {
+ var tr = self.edit_xml_dialog.$element.find("tr[id='viewedit-"+rec+"']");
+ tr.find("img[id='parentimg-"+rec+"']").attr('src','/web/static/src/img/expand.gif');
+ tr.show();
+ });
+ }
+
+});
+};
diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js
index 2946df7166c..603e2abb008 100644
--- a/addons/web/static/src/js/view_form.js
+++ b/addons/web/static/src/js/view_form.js
@@ -10,6 +10,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* view should be displayed (if there is one active).
*/
searchable: false,
+ readonly : false,
form_template: "FormView",
identifier_prefix: 'formview-',
/**
@@ -37,7 +38,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.dirty_for_user = false;
this.default_focus_field = null;
this.default_focus_button = null;
- this.registry = openerp.web.form.widgets;
+ this.registry = this.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
this.has_been_loaded = $.Deferred();
this.$form_header = null;
this.translatable_fields = [];
@@ -89,7 +90,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.fields_view = data;
var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch);
- this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'view': this });
+ this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'widget': this });
}
this.$element.html(this.rendered);
_.each(this.widgets, function(w) {
@@ -101,21 +102,11 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_pager_action(action);
});
- this.$form_header.find('button.oe_form_button_save').click(this.do_save);
- this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
+ this.$form_header.find('button.oe_form_button_save').click(this.do_save_then_readonly);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_duplicate').click(this.on_button_duplicate);
- this.$form_header.find('button.oe_form_button_toggle').click(function () {
- self.translatable_fields = [];
- self.widgets = {};
- self.fields = {};
- self.$form_header.find('button').unbind('click');
- self.registry = self.registry === openerp.web.form.widgets
- ? openerp.web.form.readonly
- : openerp.web.form.widgets;
- self.on_loaded(self.fields_view);
- self.reload();
- });
+ this.$form_header.find('button.oe_form_button_delete').click(this.on_button_delete);
+ this.$form_header.find('button.oe_form_button_toggle').click(this.on_toggle_readonly);
if (this.options.sidebar && this.options.sidebar_id) {
this.sidebar = new openerp.web.Sidebar(this, this.options.sidebar_id);
@@ -127,6 +118,23 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
}
this.has_been_loaded.resolve();
},
+ on_toggle_readonly: function() {
+ var self = this;
+ self.translatable_fields = [];
+ self.widgets = {};
+ self.fields = {};
+ self.$form_header.find('button').unbind('click');
+ self.readonly = !self.readonly;
+ self.registry = self.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
+ self.on_loaded(self.fields_view);
+ return self.reload();
+ },
+ do_set_readonly: function() {
+ return this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
+ },
+ do_set_editable: function() {
+ return !this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
+ },
do_show: function () {
var promise;
if (this.dataset.index === null) {
@@ -162,6 +170,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.$form_header.find('.oe_form_on_update').show();
this.$form_header.find('button.oe_form_button_new').show();
}
+ this.$form_header.find('.oe_form_on_readonly').toggle(this.readonly);
+ this.$form_header.find('.oe_form_on_editable').toggle(!this.readonly);
this.dirty_for_user = false;
this.datarecord = record;
for (var f in this.fields) {
@@ -342,14 +352,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
$.when(this.has_been_loaded).then(function() {
if (self.can_be_discarded()) {
var keys = _.keys(self.fields_view.fields);
- if (keys.length) {
- self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
+ $.when(self.do_set_editable()).then(function() {
+ if (keys.length) {
+ self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
+ def.resolve();
+ });
+ } else {
+ self.on_record_loaded({});
def.resolve();
- });
- } else {
- self.on_record_loaded({});
- def.resolve();
- }
+ }
+ });
}
});
return def.promise();
@@ -361,7 +373,20 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (self.can_be_discarded()) {
self.dataset.call('copy', [self.datarecord.id, {}, self.dataset.context]).then(function(new_id) {
return self.on_created({ result : new_id });
- }).then(function() {
+ }).then(self.do_set_editable).then(function() {
+ def.resolve();
+ });
+ }
+ });
+ return def.promise();
+ },
+ on_button_delete: function() {
+ var self = this;
+ var def = $.Deferred();
+ $.when(this.has_been_loaded).then(function() {
+ if (self.can_be_discarded() && self.datarecord.id) {
+ self.dataset.unlink([self.datarecord.id]).then(function() {
+ self.on_pager_action('next');
def.resolve();
});
}
@@ -379,6 +404,9 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* @param {Function} success callback on save success
* @param {Boolean} [prepend_on_create=false] if ``do_save`` creates a new record, should that record be inserted at the start of the dataset (by default, records are added at the end)
*/
+ do_save_then_readonly: function(success, prepend_on_create) {
+ return this.do_save(success, prepend_on_create).then(this.do_set_readonly);
+ },
do_save: function(success, prepend_on_create) {
var self = this;
var action = function() {
@@ -426,10 +454,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.mutating_lock = this.mutating_lock.pipe(action, action);
return this.mutating_lock;
},
- switch_readonly: function() {
- },
- switch_editable: function() {
- },
on_invalid: function() {
var msg = "<ul>";
_.each(this.fields, function(f) {
@@ -487,9 +511,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
on_action: function (action) {
console.debug('Executing action', action);
},
- do_cancel: function () {
- console.debug("Cancelling form");
- },
reload: function() {
var self = this;
var act = function() {
@@ -715,6 +736,16 @@ openerp.web.form.Widget = openerp.web.Widget.extend(/** @lends openerp.web.form.
this.invisible = this.modifiers['invisible'] === true;
this.classname = 'oe_form_' + this.type;
+ this.align = parseFloat(this.node.attrs.align);
+ if (isNaN(this.align) || this.align === 1) {
+ this.align = 'right';
+ } else if (this.align === 0) {
+ this.align = 'left';
+ } else {
+ this.align = 'center';
+ }
+
+
this.width = this.node.attrs.width;
},
start: function() {
@@ -1044,8 +1075,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
this._super(view, node);
- // TODO fme: support for attrs.align
- if (this.node.tag == 'label' && (this.node.attrs.colspan || (this.string && this.string.length > 32))) {
+ if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) {
this.template = "WidgetParagraph";
this.colspan = parseInt(this.node.attrs.colspan || 1, 10);
} else {
@@ -1170,6 +1200,10 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f
openerp.web.form.FieldChar = openerp.web.form.Field.extend({
template: 'FieldChar',
+ init: function (view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
start: function() {
this._super.apply(this, arguments);
this.$element.find('input').change(this.on_ui_change);
@@ -1419,11 +1453,7 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({
start: function() {
var self = this;
this._super.apply(this, arguments);
- this.$element.find('input').click(function() {
- if ($(this).is(':checked') != self.value) {
- self.on_ui_change();
- }
- });
+ this.$element.find('input').click(self.on_ui_change);
},
set_value: function(value) {
this._super.apply(this, arguments);
@@ -1632,6 +1662,11 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
} else {
$("#" + self.cm_id + " .oe_m2o_menu_item_mandatory").addClass("oe-m2o-disabled-cm");
}
+ if (!self.readonly) {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").removeClass("oe-m2o-disabled-cm");
+ } else {
+ $("#" + self.cm_id + " .oe_m2o_menu_item_noreadonly").addClass("oe-m2o-disabled-cm");
+ }
return true;
}, menuStyle: {width: "200px"}
});
@@ -1651,6 +1686,8 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
}
});
this.$drop_down.click(function() {
+ if (self.readonly)
+ return;
if (self.$input.autocomplete("widget").is(":visible")) {
self.$input.autocomplete("close");
} else {
@@ -1811,7 +1848,7 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
self.original_value = undefined;
self._change_int_ext_value(rval);
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
real_set_value(data[0]);
@@ -1857,6 +1894,10 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
},
focus: function () {
this.$input.focus();
+ },
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ this.$input.attr('disabled', this.readonly);
}
});
@@ -1910,7 +1951,8 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
multi_selection: false,
init: function(view, node) {
this._super(view, node);
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
this.is_setted = $.Deferred();
this.form_last_update = $.Deferred();
this.init_form_last_update = this.form_last_update;
@@ -1928,8 +1970,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
self.on_ui_change();
});
+ this.is_setted.then(function() {
+ self.load_views();
+ });
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_views: function() {
+ var self = this;
+
var modes = this.node.attrs.mode;
- modes = !!modes ? modes.split(",") : ["tree", "form"];
+ modes = !!modes ? modes.split(",") : ["tree"];
var views = [];
_.each(modes, function(mode) {
var view = {
@@ -1942,25 +1994,38 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
}
if(view.view_type === "list") {
view.options.selectable = self.multi_selection;
+ if (self.is_readonly()) {
+ view.options.addable = null;
+ view.options.deletable = null;
+ }
} else if (view.view_type === "form") {
view.options.not_interactible_on_create = true;
}
views.push(view);
});
this.views = views;
-
+
this.viewmanager = new openerp.web.ViewManager(this, this.dataset, views);
this.viewmanager.registry = openerp.web.views.clone({
list: 'openerp.web.form.One2ManyListView',
- form: 'openerp.web.form.One2ManyFormView'
+ form: 'openerp.web.FormView'
});
var once = $.Deferred().then(function() {
self.init_form_last_update.resolve();
});
+ var def = $.Deferred().then(function() {
+ self.initial_is_loaded.resolve();
+ });
this.viewmanager.on_controller_inited.add_last(function(view_type, controller) {
if (view_type == "list") {
controller.o2m = self;
+ if (self.is_readonly())
+ controller.set_editable(false);
} else if (view_type == "form") {
+ if (self.is_readonly()) {
+ controller.on_toggle_readonly();
+ $(controller.$element.find(".oe_form_buttons")[0]).children().remove();
+ }
controller.on_record_loaded.add_last(function() {
once.resolve();
});
@@ -1971,33 +2036,40 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
} else if (view_type == "graph") {
self.reload_current_view()
}
- self.is_started.resolve();
+ def.resolve();
});
- this.viewmanager.on_mode_switch.add_first(function() {
- self.save_form_view();
+ this.viewmanager.on_mode_switch.add_first(function(n_mode, b, c, d, e) {
+ $.when(self.save_form_view()).then(function() {
+ if(n_mode === "list")
+ setTimeout(function() {self.reload_current_view();}, 0);
+ });
});
this.is_setted.then(function() {
setTimeout(function () {
self.viewmanager.appendTo(self.$element);
}, 0);
});
+ return def;
},
reload_current_view: function() {
var self = this;
- var view = self.viewmanager.views[self.viewmanager.active_view].controller;
- if(self.viewmanager.active_view === "list") {
- view.reload_content();
- } else if (self.viewmanager.active_view === "form") {
- if (this.dataset.index === null && this.dataset.ids.length >= 1) {
- this.dataset.index = 0;
- }
- var act = function() {
- return view.do_show();
+ self.is_loaded = self.is_loaded.pipe(function() {
+ var view = self.viewmanager.views[self.viewmanager.active_view].controller;
+ if(self.viewmanager.active_view === "list") {
+ return view.reload_content();
+ } else if (self.viewmanager.active_view === "form") {
+ if (self.dataset.index === null && self.dataset.ids.length >= 1) {
+ self.dataset.index = 0;
+ }
+ var act = function() {
+ return view.do_show();
+ }
+ self.form_last_update = self.form_last_update.pipe(act, act);
+ return self.form_last_update;
+ } else if (self.viewmanager.active_view === "graph") {
+ return view.do_search(self.build_domain(), self.dataset.get_context(), []);
}
- this.form_last_update = this.form_last_update.pipe(act, act);;
- } else if (self.viewmanager.active_view === "graph") {
- view.do_search(this.build_domain(), this.dataset.get_context(), []);
- }
+ });
},
set_value: function(value) {
value = value || [];
@@ -2054,9 +2126,7 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
if (this.dataset.index === null && this.dataset.ids.length > 0) {
this.dataset.index = 0;
}
- $.when(this.is_started).then(function() {
- self.reload_current_view();
- });
+ self.reload_current_view();
this.is_setted.resolve();
},
get_value: function() {
@@ -2120,7 +2190,18 @@ openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({
},
update_dom: function() {
this._super.apply(this, arguments);
- this.$element.toggleClass('disabled', this.readonly);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.viewmanager) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.viewmanager.stop();
+ return $.when(self.load_views()).then(function() {
+ self.reload_current_view();
+ });
+ });
+ }
+ }
}
});
@@ -2131,9 +2212,6 @@ openerp.web.form.One2ManyDataSet = openerp.web.BufferedDataSet.extend({
}
});
-openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({
-});
-
openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
do_add_record: function () {
if (this.options.editable) {
@@ -2172,7 +2250,8 @@ openerp.web.form.One2ManyListView = openerp.web.ListView.extend({
read_function: function() {
return self.o2m.dataset.read_ids.apply(self.o2m.dataset, arguments);
},
- form_view_options: {'not_interactible_on_create':true}
+ form_view_options: {'not_interactible_on_create':true},
+ readonly: self.o2m.is_readonly()
});
pop.on_write.add(function(id, data) {
self.o2m.dataset.write(id, data, {}, function(r) {
@@ -2188,7 +2267,9 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
init: function(view, node) {
this._super(view, node);
this.list_id = _.uniqueId("many2many");
- this.is_started = $.Deferred();
+ this.is_loaded = $.Deferred();
+ this.initial_is_loaded = this.is_loaded;
+ this.is_setted = $.Deferred();
},
start: function() {
this._super.apply(this, arguments);
@@ -2200,18 +2281,10 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this.dataset.on_unlink.add_last(function(ids) {
self.on_ui_change();
});
-
- this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
- 'addable': 'Add',
- 'selectable': self.multi_selection
- });
- this.list_view.m2m_field = this;
- this.list_view.on_loaded.add_last(function() {
- self.is_started.resolve();
+
+ this.is_setted.then(function() {
+ self.load_view();
});
- setTimeout(function () {
- self.list_view.appendTo($("#" + self.list_id));
- }, 0);
},
set_value: function(value) {
value = value || [];
@@ -2221,16 +2294,56 @@ openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({
this._super(value);
this.dataset.set_ids(value);
var self = this;
- $.when(this.is_started).then(function() {
- self.list_view.reload_content();
- });
+ self.reload_content();
+ this.is_setted.resolve();
},
get_value: function() {
return [commands.replace_with(this.dataset.ids)];
},
validate: function() {
this.invalid = false;
- // TODO niv
+ },
+ is_readonly: function() {
+ return this.readonly || this.force_readonly;
+ },
+ load_view: function() {
+ var self = this;
+ this.list_view = new openerp.web.form.Many2ManyListView(this, this.dataset, false, {
+ 'addable': self.is_readonly() ? null : 'Add',
+ 'deletable': self.is_readonly() ? false : true,
+ 'selectable': self.multi_selection
+ });
+ this.list_view.m2m_field = this;
+ var loaded = $.Deferred();
+ this.list_view.on_loaded.add_last(function() {
+ self.initial_is_loaded.resolve();
+ loaded.resolve();
+ });
+ setTimeout(function () {
+ self.list_view.appendTo($("#" + self.list_id));
+ }, 0);
+ return loaded;
+ },
+ reload_content: function() {
+ var self = this;
+ this.is_loaded = this.is_loaded.pipe(function() {
+ return self.list_view.reload_content();
+ });
+ },
+ update_dom: function() {
+ this._super.apply(this, arguments);
+ var self = this;
+ if (this.previous_readonly !== this.readonly) {
+ this.previous_readonly = this.readonly;
+ if (this.list_view) {
+ this.is_loaded = this.is_loaded.pipe(function() {
+ self.list_view.stop();
+ return $.when(self.load_view()).then(function() {
+ self.reload_content();
+ });
+ });
+ }
+ }
}
});
@@ -2334,10 +2447,7 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
this.searchview.stop();
}
this.searchview = new openerp.web.SearchView(this,
- this.dataset, false, {
- "selectable": !this.options.disable_multiple_selection,
- "deletable": false
- });
+ this.dataset, false, {});
this.searchview.on_search.add(function(domains, contexts, groupbys) {
if (self.initial_ids) {
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
@@ -2364,7 +2474,9 @@ openerp.web.form.SelectCreatePopup = openerp.web.OldWidget.extend(/** @lends ope
});
self.view_list = new openerp.web.form.SelectCreateListView(self,
self.dataset, false,
- _.extend({'deletable': false}, self.options.list_view_options || {}));
+ _.extend({'deletable': false,
+ 'selectable': !self.options.disable_multiple_selection
+ }, self.options.list_view_options || {}));
self.view_list.popup = self;
self.view_list.appendTo($("#" + self.element_id + "_view_list")).pipe(function() {
self.view_list.do_show();
@@ -2483,6 +2595,7 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
* - read_function
* - parent_view
* - form_view_options
+ * - readonly
*/
show_element: function(model, row_id, context, options) {
this.model = model;
@@ -2522,7 +2635,13 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
this.view_form.set_embedded_view(this.options.alternative_form_view);
}
this.view_form.appendTo(this.$element.find("#" + this.element_id + "_view_form"));
+ var once = $.Deferred().then(function() {
+ if (self.options.readonly) {
+ self.view_form.on_toggle_readonly();
+ }
+ });
this.view_form.on_loaded.add_last(function() {
+ once.resolve();
var $buttons = self.view_form.$element.find(".oe_form_buttons");
$buttons.html(QWeb.render("FormOpenPopup.form.buttons"));
var $nbutton = $buttons.find(".oe_formopenpopup-form-save");
@@ -2535,6 +2654,10 @@ openerp.web.form.FormOpenPopup = openerp.web.OldWidget.extend(/** @lends openerp
$cbutton.click(function() {
self.stop();
});
+ if (self.options.readonly) {
+ $nbutton.hide();
+ $cbutton.text(_t("Close"));
+ }
self.view_form.do_show();
});
this.dataset.on_write.add(this.on_write);
@@ -2817,17 +2940,21 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({
}
});
-openerp.web.form.WidgetNotebookReadonly = openerp.web.form.WidgetNotebook.extend({
- template: 'WidgetNotebook.readonly'
-});
openerp.web.form.FieldReadonly = openerp.web.form.Field.extend({
});
openerp.web.form.FieldCharReadonly = openerp.web.form.FieldReadonly.extend({
template: 'FieldChar.readonly',
+ init: function(view, node) {
+ this._super(view, node);
+ this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1';
+ },
set_value: function (value) {
this._super.apply(this, arguments);
var show_value = openerp.web.format_value(value, this, '');
+ if (this.password) {
+ show_value = new Array(show_value.length + 1).join('*');
+ }
this.$element.find('div').text(show_value);
return show_value;
}
@@ -2855,7 +2982,7 @@ openerp.web.form.FieldUrlReadonly = openerp.web.form.FieldURIReadonly.extend({
});
openerp.web.form.FieldBooleanReadonly = openerp.web.form.FieldCharReadonly.extend({
set_value: function (value) {
- this._super(value ? '\u2714' : '\u2718');
+ this._super(value ? '\u2611' : '\u2610');
}
});
openerp.web.form.FieldSelectionReadonly = openerp.web.form.FieldReadonly.extend({
@@ -2890,9 +3017,17 @@ openerp.web.form.FieldMany2OneReadonly = openerp.web.form.FieldCharReadonly.exte
self.update_dom();
self.on_value_changed();
var real_set_value = function(rval) {
- self.$element.find('div').text(rval ? rval[1] : '');
+ self.value = rval;
+ var div = $(self.$element.find('div'));
+ div.html('<a href="javascript:void(0)"></a>');
+ var a = $(div.find("a"));
+ a.text(rval ? rval[1] : '');
+ a.click(function() {
+ var pop = new openerp.web.form.FormOpenPopup(self.view);
+ pop.show_element(self.field.relation, self.value[0],self.build_context(), {readonly:true});
+ });
};
- if(typeof(value) === "number") {
+ if (value && !(value instanceof Array)) {
var dataset = new openerp.web.DataSetStatic(
this, this.field.relation, self.build_context());
dataset.name_get([value], function(data) {
@@ -2937,8 +3072,14 @@ openerp.web.form.widgets = new openerp.web.Registry({
'binary': 'openerp.web.form.FieldBinaryFile',
'statusbar': 'openerp.web.form.FieldStatus'
});
+
+openerp.web.form.FieldMany2ManyReadonly = openerp.web.form.FieldMany2Many.extend({
+ force_readonly: true
+});
+openerp.web.form.FieldOne2ManyReadonly = openerp.web.form.FieldOne2Many.extend({
+ force_readonly: true
+});
openerp.web.form.readonly = openerp.web.form.widgets.clone({
- 'notebook': 'openerp.web.form.WidgetNotebookReadonly',
'char': 'openerp.web.form.FieldCharReadonly',
'email': 'openerp.web.form.FieldEmailReadonly',
'url': 'openerp.web.form.FieldUrlReadonly',
@@ -2948,6 +3089,9 @@ openerp.web.form.readonly = openerp.web.form.widgets.clone({
'datetime': 'openerp.web.form.FieldCharReadonly',
'selection' : 'openerp.web.form.FieldSelectionReadonly',
'many2one': 'openerp.web.form.FieldMany2OneReadonly',
+ 'many2many' : 'openerp.web.form.FieldMany2ManyReadonly',
+ 'one2many' : 'openerp.web.form.FieldOne2ManyReadonly',
+ 'one2many_list' : 'openerp.web.form.FieldOne2ManyReadonly',
'boolean': 'openerp.web.form.FieldBooleanReadonly',
'float': 'openerp.web.form.FieldCharReadonly',
'integer': 'openerp.web.form.FieldCharReadonly',
diff --git a/addons/web/static/src/js/view_list.js b/addons/web/static/src/js/view_list.js
index d09ec1d3035..e891a6c7db7 100644
--- a/addons/web/static/src/js/view_list.js
+++ b/addons/web/static/src/js/view_list.js
@@ -11,7 +11,7 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
// whether the column headers should be displayed
'header': true,
// display addition button, with that label
- 'addable': _t("New"),
+ 'addable': _t("Create"),
// whether the list view can be sorted, note that once a view has been
// sorted it can not be reordered anymore
'sortable': true,
@@ -201,8 +201,15 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
this.setup_columns(this.fields_view.fields, grouped);
this.$element.html(QWeb.render("ListView", this));
-
// Head hook
+ this.$element.find('.all-record-selector').click(function(){
+ self.$element.find('.oe-record-selector input').prop('checked',
+ self.$element.find('.all-record-selector').prop('checked') || false);
+ var selection = self.groups.get_selection();
+ $(self.groups).trigger(
+ 'selected', [selection.ids, selection.records]);
+ });
+
this.$element.find('.oe-list-add')
.click(this.do_add_record)
.attr('disabled', grouped && this.options.editable);
@@ -424,10 +431,13 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
},
/**
* re-renders the content of the list view
+ *
+ * @returns {$.Deferred} promise to content reloading
*/
reload_content: function () {
var self = this;
this.records.reset();
+ var reloaded = $.Deferred();
this.$element.find('.oe-listview-content').append(
this.groups.render(function () {
if (self.dataset.index == null) {
@@ -438,7 +448,9 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
}
}
self.compute_aggregates();
+ reloaded.resolve();
}));
+ return reloaded.promise();
},
/**
* Handler for the result of eval_domain_and_context, actually perform the
@@ -512,6 +524,17 @@ openerp.web.ListView = openerp.web.View.extend( /** @lends openerp.web.ListView#
return field.name === name;
});
if (!action) { return; }
+
+ var c = new openerp.web.CompoundContext();
+ c.set_eval_context(_.extend({
+ active_id: id,
+ active_ids: [id],
+ active_model: this.dataset.model
+ }, this.records.get(id).toContext()));
+ if (action.context) {
+ c.add(action.context);
+ }
+ action.context = c;
this.do_execute_action(action, this.dataset, id, callback);
},
/**
@@ -1201,6 +1224,10 @@ openerp.web.ListView.Groups = openerp.web.Class.extend( /** @lends openerp.web.L
var options = { offset: page * limit, limit: limit };
//TODO xmo: investigate why we need to put the setTimeout
setTimeout(function() {dataset.read_slice(fields, options , function (records) {
+ // FIXME: ignominious hacks, parents (aka form view) should not send two ListView#reload_content concurrently
+ if (self.records.length) {
+ self.records.reset(null, {silent: true});
+ }
if (!self.datagroup.openable) {
view.configure_pager(dataset);
} else {
@@ -1430,6 +1457,25 @@ var Record = openerp.web.Class.extend(/** @lends Record# */{
}
return {data: form_data};
+ },
+ /**
+ * Converts the current record to a format expected by context evaluations
+ * (identical to record.attributes, except m2o fields are their integer
+ * value rather than a pair)
+ */
+ toContext: function () {
+ var output = {}, attrs = this.attributes;
+ for(var k in attrs) {
+ var val = attrs[k];
+ if (typeof val !== 'object') {
+ output[k] = val;
+ } else if (val instanceof Array) {
+ output[k] = val[0];
+ } else {
+ throw new Error("Can't convert value " + val + " to context");
+ }
+ }
+ return output;
}
});
Record.include(Events);
@@ -1541,7 +1587,8 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
* @param {Array} [records]
* @returns this
*/
- reset: function (records) {
+ reset: function (records, options) {
+ options = options || {};
_(this._proxies).each(function (proxy) {
proxy.reset();
});
@@ -1552,7 +1599,9 @@ var Collection = openerp.web.Class.extend(/** @lends Collection# */{
if (records) {
this.add(records);
}
- this.trigger('reset', this);
+ if (!options.silent) {
+ this.trigger('reset', this);
+ }
return this;
},
/**
diff --git a/addons/web/static/src/js/view_list_editable.js b/addons/web/static/src/js/view_list_editable.js
index 4cc081a6266..dba0a1abba4 100644
--- a/addons/web/static/src/js/view_list_editable.js
+++ b/addons/web/static/src/js/view_list_editable.js
@@ -78,6 +78,17 @@ openerp.web.list_editable = function (openerp) {
// tree/@editable takes priority on everything else if present.
this.options.editable = data.arch.attrs.editable || this.options.editable;
return this._super(data, grouped);
+ },
+ /**
+ * Ensures the editable list is saved (saves any pending edition if
+ * needed, or tries to)
+ *
+ * Returns a deferred to the end of the saving.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return this.groups.ensure_saved();
}
});
@@ -86,6 +97,18 @@ openerp.web.list_editable = function (openerp) {
new_record: function () {
// TODO: handle multiple children
this.children[null].new_record();
+ },
+ /**
+ * Ensures descendant editable List instances are all saved if they have
+ * pending editions.
+ *
+ * @returns {$.Deferred}
+ */
+ ensure_saved: function () {
+ return $.when.apply(null,
+ _.invoke(
+ _.values(this.children),
+ 'ensure_saved'));
}
});
@@ -254,9 +277,11 @@ openerp.web.list_editable = function (openerp) {
* sibling if asked.
*
* @param {Boolean} [edit_next=false] should the next row become editable
+ * @returns {$.Deferred}
*/
save_row: function (edit_next) {
- var self = this;
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ var self = this, done = $.Deferred();
this.edition_form.do_save(function (result) {
if (result.created && !self.edition_id) {
self.records.add({id: result.result},
@@ -267,28 +292,44 @@ openerp.web.list_editable = function (openerp) {
next_record = self.records.at(
self.records.indexOf(edited_record) + 1);
- self.handle_onwrite(self.edition_id);
- self.cancel_pending_edition().then(function () {
- $(self).trigger('saved', [self.dataset]);
- if (!edit_next) {
- return;
- }
- if (result.created) {
- self.new_record();
- return;
- }
- var next_record_id;
- if (next_record) {
- next_record_id = next_record.get('id');
- self.dataset.index = _(self.dataset.ids)
- .indexOf(next_record_id);
- } else {
- self.dataset.index = 0;
- next_record_id = self.records.at(0).get('id');
- }
- self.edit_record(next_record_id);
- });
- }, this.options.editable === 'top');
+ $.when(
+ self.handle_onwrite(self.edition_id),
+ self.cancel_pending_edition().then(function () {
+ $(self).trigger('saved', [self.dataset]);
+ if (!edit_next) {
+ return;
+ }
+ if (result.created) {
+ self.new_record();
+ return;
+ }
+ var next_record_id;
+ if (next_record) {
+ next_record_id = next_record.get('id');
+ self.dataset.index = _(self.dataset.ids)
+ .indexOf(next_record_id);
+ } else {
+ self.dataset.index = 0;
+ next_record_id = self.records.at(0).get('id');
+ }
+ self.edit_record(next_record_id);
+ })).then(function () {
+ done.resolve();
+ });
+ }, this.options.editable === 'top').fail(function () {
+ done.reject();
+ });
+ return done.promise();
+ },
+ /**
+ * If the current list is being edited, ensures it's saved
+ */
+ ensure_saved: function () {
+ if (this.edition) {
+ return this.save_row();
+ }
+ //noinspection JSPotentiallyInvalidConstructorUsage
+ return $.Deferred().resolve().promise();
},
/**
* Cancels the edition of the row for the current dataset index
diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js
index f402a51bf7e..62928401492 100644
--- a/addons/web/static/src/js/views.js
+++ b/addons/web/static/src/js/views.js
@@ -2,21 +2,21 @@
* OpenERP web library
*---------------------------------------------------------*/
-openerp.web.views = function(db) {
+openerp.web.views = function(session) {
-var _t = db.web._t;
+var _t = session.web._t;
/**
* Registry for all the client actions key: tag value: widget
*/
-db.web.client_actions = new db.web.Registry();
+session.web.client_actions = new session.web.Registry();
/**
* Registry for all the main views
*/
-db.web.views = new db.web.Registry();
+session.web.views = new session.web.Registry();
-db.web.ActionManager = db.web.Widget.extend({
+session.web.ActionManager = session.web.Widget.extend({
identifier_prefix: "actionmanager",
init: function(parent) {
this._super(parent);
@@ -93,20 +93,20 @@ db.web.ActionManager = db.web.Widget.extend({
ir_actions_act_window: function (action, on_close) {
if (action.target === 'new') {
if (this.dialog == null) {
- this.dialog = new db.web.Dialog(this, { title: action.name, width: '80%' });
+ this.dialog = new session.web.Dialog(this, { title: action.name, width: '80%' });
if(on_close)
this.dialog.on_close.add(on_close);
this.dialog.start();
} else {
this.dialog_viewmanager.stop();
}
- this.dialog_viewmanager = new db.web.ViewManagerAction(this, action);
+ this.dialog_viewmanager = new session.web.ViewManagerAction(this, action);
this.dialog_viewmanager.appendTo(this.dialog.$element);
this.dialog.open();
} else {
this.dialog_stop();
this.content_stop();
- this.inner_viewmanager = new db.web.ViewManagerAction(this, action);
+ this.inner_viewmanager = new session.web.ViewManagerAction(this, action);
this.inner_viewmanager.appendTo(this.$element);
this.url_update(action);
}
@@ -124,7 +124,7 @@ db.web.ActionManager = db.web.Widget.extend({
if (this.dialog && action.context) {
var model = action.context.active_model;
if (model === 'base.module.upgrade' || model === 'base.setup.installer' || model === 'base.module.upgrade') {
- db.webclient.do_reload();
+ session.webclient.do_reload();
}
}
this.dialog_stop();
@@ -140,7 +140,7 @@ db.web.ActionManager = db.web.Widget.extend({
},
ir_actions_client: function (action) {
this.content_stop();
- var ClientWidget = db.web.client_actions.get_object(action.tag);
+ var ClientWidget = session.web.client_actions.get_object(action.tag);
(this.client_widget = new ClientWidget(this, action.params)).appendTo(this);
},
ir_actions_report_xml: function(action) {
@@ -164,12 +164,12 @@ db.web.ActionManager = db.web.Widget.extend({
}
});
-db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
+session.web.ViewManager = session.web.Widget.extend(/** @lends session.web.ViewManager# */{
identifier_prefix: "viewmanager",
template: "ViewManager",
/**
- * @constructs db.web.ViewManager
- * @extends db.web.Widget
+ * @constructs session.web.ViewManager
+ * @extends session.web.Widget
*
* @param parent
* @param dataset
@@ -185,10 +185,10 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
this.views_src = _.map(views, function(x) {return x instanceof Array? {view_id: x[0], view_type: x[1]} : x;});
this.views = {};
this.flags = this.flags || {};
- this.registry = db.web.views;
+ this.registry = session.web.views;
},
render: function() {
- return db.web.qweb.render(this.template, {
+ return session.web.qweb.render(this.template, {
self: this,
prefix: this.element_id,
views: this.views_src});
@@ -271,6 +271,10 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
}
}
}
+ $.when(view_promise).then(function () {
+ self.$element.find('.oe_view_title:first').text(
+ self.display_title());
+ });
return view_promise;
},
/**
@@ -284,7 +288,7 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
if (this.searchview) {
this.searchview.stop();
}
- this.searchview = new db.web.SearchView(
+ this.searchview = new session.web.SearchView(
this, this.dataset,
view_id, search_defaults, this.flags.search_view === false);
@@ -331,16 +335,24 @@ db.web.ViewManager = db.web.Widget.extend(/** @lends db.web.ViewManager# */{
/**
* Called by children view after executing an action
*/
- on_action_executed: function () {}
+ on_action_executed: function () {},
+ display_title: function () {
+ var view = this.views[this.active_view];
+ if (view) {
+ // ick
+ return view.controller.fields_view.arch.attrs.string;
+ }
+ return '';
+ }
});
-db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
+session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepnerp.web.ViewManagerAction# */{
template:"ViewManagerAction",
/**
- * @constructs db.web.ViewManagerAction
- * @extends db.web.ViewManager
+ * @constructs session.web.ViewManagerAction
+ * @extends session.web.ViewManager
*
- * @param {db.web.ActionManager} parent parent object/widget
+ * @param {session.web.ActionManager} parent parent object/widget
* @param {Object} action descriptor for the action this viewmanager needs to manage its views.
*/
init: function(parent, action) {
@@ -350,7 +362,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
this._super(parent, null, action.views);
this.session = parent.session;
this.action = action;
- var dataset = new db.web.DataSetSearch(this, action.res_model, action.context, action.domain);
+ var dataset = new session.web.DataSetSearch(this, action.res_model, action.context, action.domain);
if (action.res_id) {
dataset.ids.push(action.res_id);
dataset.index = 0;
@@ -400,12 +412,12 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
this.$element.find('.oe_get_xml_view').click(function () {
// TODO: add search view?
- $('<pre>').text(db.web.json_node_to_xml(
+ $('<pre>').text(session.web.json_node_to_xml(
self.views[self.active_view].controller.fields_view.arch, true))
.dialog({ width: '95%'});
});
if (this.action.help && !this.flags.low_profile) {
- var Users = new db.web.DataSet(self, 'res.users'),
+ var Users = new session.web.DataSet(self, 'res.users'),
header = this.$element.find('.oe-view-manager-header');
header.delegate('blockquote button', 'click', function() {
var $this = $(this);
@@ -444,6 +456,16 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
if (!self.action.name && fvg) {
self.$element.find('.oe_view_title').text(fvg.arch.attrs.string || fvg.name);
}
+
+ var $title = self.$element.find('.oe_view_title'),
+ $search_prefix = $title.find('span');
+ if (controller.searchable !== false) {
+ if (!$search_prefix.length) {
+ $title.prepend('<span>' + _t("Search:") + '</span>');
+ }
+ } else {
+ $search_prefix.remove();
+ }
});
},
shortcut_check : function(view) {
@@ -451,7 +473,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
var grandparent = this.widget_parent && this.widget_parent.widget_parent;
// display shortcuts if on the first view for the action
var $shortcut_toggle = this.$element.find('.oe-shortcut-toggle');
- if (!(grandparent instanceof db.web.WebClient) ||
+ if (!(grandparent instanceof session.web.WebClient) ||
!(view.view_type === this.views_src[0].view_type
&& view.view_id === this.views_src[0].view_id)) {
$shortcut_toggle.hide();
@@ -488,7 +510,7 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
* Intercept do_action resolution from children views
*/
on_action_executed: function () {
- return new db.web.DataSet(this, 'res.log')
+ return new session.web.DataSet(this, 'res.log')
.call('get', [], this.do_display_log);
},
/**
@@ -512,10 +534,13 @@ db.web.ViewManagerAction = db.web.ViewManager.extend(/** @lends oepnerp.web.View
return false;
});
});
+ },
+ display_title: function () {
+ return this.action.name;
}
});
-db.web.Sidebar = db.web.Widget.extend({
+session.web.Sidebar = session.web.Widget.extend({
init: function(parent, element_id) {
this._super(parent, element_id);
this.items = {};
@@ -524,7 +549,7 @@ db.web.Sidebar = db.web.Widget.extend({
start: function() {
this._super(this);
var self = this;
- this.$element.html(db.web.qweb.render('Sidebar'));
+ this.$element.html(session.web.qweb.render('Sidebar'));
this.$element.find(".toggle-sidebar").click(function(e) {
self.do_toggle();
});
@@ -544,7 +569,7 @@ db.web.Sidebar = db.web.Widget.extend({
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
@@ -553,7 +578,7 @@ db.web.Sidebar = db.web.Widget.extend({
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
- title: _t("Manage views of the current object"),
+ title: _t("Manage views of the current object")
}
]);
@@ -561,10 +586,10 @@ db.web.Sidebar = db.web.Widget.extend({
this.add_items('other', [
{
label: _t("Import"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Export"),
- callback: this.call_default_on_sidebar,
+ callback: this.call_default_on_sidebar
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
@@ -601,10 +626,10 @@ db.web.Sidebar = db.web.Widget.extend({
if(!$section) {
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
- var $section = $(db.web.qweb.render("Sidebar.section", {
+ var $section = $(session.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
- classname: 'oe_sidebar_' + code,
+ classname: 'oe_sidebar_' + code
}));
$section.appendTo(this.$element.find('div.sidebar-actions'));
this.sections[code] = $section;
@@ -633,7 +658,7 @@ db.web.Sidebar = db.web.Widget.extend({
this.items[items[i].element_id] = items[i];
}
- var $items = $(db.web.qweb.render("Sidebar.section.items", {items: items}));
+ var $items = $(session.web.qweb.render("Sidebar.section.items", {items: items}));
$items.find('a.oe_sidebar_action_a').click(function() {
var item = self.items[$(this).attr('id')];
@@ -687,7 +712,7 @@ db.web.Sidebar = db.web.Widget.extend({
}
});
-db.web.TranslateDialog = db.web.Dialog.extend({
+session.web.TranslateDialog = session.web.Dialog.extend({
dialog_title: _t("Translations"),
init: function(view) {
// TODO fme: should add the language to fields_view_get because between the fields view get
@@ -707,14 +732,14 @@ db.web.TranslateDialog = db.web.Dialog.extend({
this.translatable_fields_keys = _.map(this.view.translatable_fields || [], function(i) { return i.name });
this.languages = null;
this.languages_loaded = $.Deferred();
- (new db.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
+ (new session.web.DataSetSearch(this, 'res.lang', this.view.dataset.get_context(),
[['translatable', '=', '1']])).read_slice(['code', 'name'], { sort: 'id' }, this.on_languages_loaded);
},
start: function() {
var self = this;
this._super();
$.when(this.languages_loaded).then(function() {
- self.$element.html(db.web.qweb.render('TranslateDialog', { widget: self }));
+ self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.tabs();
if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
self.hide_tabs('fields');
@@ -819,7 +844,7 @@ db.web.TranslateDialog = db.web.Dialog.extend({
}
});
-db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
+session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
template: "EmptyComponent",
set_default_options: function(options) {
this.options = options || {};
@@ -833,7 +858,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
open_translate_dialog: function(field) {
if (!this.translate_dialog) {
- this.translate_dialog = new db.web.TranslateDialog(this).start();
+ this.translate_dialog = new session.web.TranslateDialog(this).start();
}
this.translate_dialog.open(field);
},
@@ -845,7 +870,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
* @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``)
* @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'``
* @param {Object} [action_data.context=null] additional action context, to add to the current context
- * @param {db.web.DataSet} dataset a dataset object used to communicate with the server
+ * @param {session.web.DataSet} dataset a dataset object used to communicate with the server
* @param {Object} [record_id] the identifier of the object on which the action is to be applied
* @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action)
*/
@@ -857,12 +882,12 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
return self.widget_parent.on_action_executed.apply(null, arguments);
}
};
- var context = new db.web.CompoundContext(dataset.get_context(), action_data.context || {});
+ var context = new session.web.CompoundContext(dataset.get_context(), action_data.context || {});
var handler = function (r) {
var action = r.result;
if (action && action.constructor == Object) {
- var ncontext = new db.web.CompoundContext(context);
+ var ncontext = new session.web.CompoundContext(context);
if (record_id) {
ncontext.add({
active_id: record_id,
@@ -899,7 +924,7 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
/**
* Directly set a view to use instead of calling fields_view_get. This method must
* be called before start(). When an embedded view is set, underlying implementations
- * of db.web.View must use the provided view instead of any other one.
+ * of session.web.View must use the provided view instead of any other one.
*
* @param embedded_view A view.
*/
@@ -917,7 +942,8 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
},
on_sidebar_manage_views: function() {
if (this.fields_view && this.fields_view.arch) {
- $('<xmp>' + db.web.json_node_to_xml(this.fields_view.arch, true) + '</xmp>').dialog({ width: '95%', height: 600});
+ var view_editor = new session.web.ViewEditor(this, this.$element, this.dataset, this.fields_view.arch);
+ view_editor.start();
} else {
this.do_warn("Manage Views", "Could not find current view declaration");
}
@@ -929,11 +955,11 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
console.log('Todo');
},
on_sidebar_import: function() {
- var import_view = new db.web.DataImport(this, this.dataset);
+ var import_view = new session.web.DataImport(this, this.dataset);
import_view.start();
},
on_sidebar_export: function() {
- var export_view = new db.web.DataExport(this, this.dataset);
+ var export_view = new session.web.DataExport(this, this.dataset);
export_view.start();
},
on_sidebar_translate: function() {
@@ -943,19 +969,19 @@ db.web.View = db.web.Widget.extend(/** @lends db.web.View# */{
}
});
-db.web.json_node_to_xml = function(node, single_quote, indent) {
+session.web.json_node_to_xml = function(node, human_readable, indent) {
// For debugging purpose, this function will convert a json node back to xml
// Maybe usefull for xml view editor
+ indent = indent || 0;
+ var sindent = (human_readable ? (new Array(indent + 1).join('\t')) : ''),
+ r = sindent + '<' + node.tag,
+ cr = human_readable ? '\n' : '';
if (typeof(node) === 'string') {
- return node;
- }
- else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
+ return sindent + node;
+ } else if (typeof(node.tag) !== 'string' || !node.children instanceof Array || !node.attrs instanceof Object) {
throw("Node a json node");
}
- indent = indent || 0;
- var sindent = new Array(indent + 1).join('\t'),
- r = sindent + '<' + node.tag;
for (var attr in node.attrs) {
var vattr = node.attrs[attr];
if (typeof(vattr) !== 'string') {
@@ -963,19 +989,19 @@ db.web.json_node_to_xml = function(node, single_quote, indent) {
vattr = JSON.stringify(vattr);
}
vattr = vattr.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
- if (single_quote) {
+ if (human_readable) {
vattr = vattr.replace(/&quot;/g, "'");
}
r += ' ' + attr + '="' + vattr + '"';
}
if (node.children && node.children.length) {
- r += '>\n';
+ r += '>' + cr;
var childs = [];
for (var i = 0, ii = node.children.length; i < ii; i++) {
- childs.push(db.web.json_node_to_xml(node.children[i], single_quote, indent + 1));
+ childs.push(session.web.json_node_to_xml(node.children[i], human_readable, indent + 1));
}
- r += childs.join('\n');
- r += '\n' + sindent + '</' + node.tag + '>';
+ r += childs.join(cr);
+ r += cr + sindent + '</' + node.tag + '>';
return r;
} else {
return r + '/>';
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 7720ae2d38b..1fc98ba34ee 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -415,6 +415,9 @@
<tr>
<td class="view-manager-main-content">
<div class="oe-view-manager-header">
+ <h2 class="oe_view_title" t-if="self.flags.display_title !== false">
+ <t t-esc="self.display_title()"/>
+ </h2>
<div class="oe_vm_switch">
<t t-if="views.length != 1" t-foreach="views" t-as="view">
<button type="button" t-att-data-view-type="view.view_type">
@@ -452,9 +455,6 @@
<button t-if="self.session.debug" class="oe_get_xml_view">
View#<span></span>
</button>
- <h2 class="oe_view_title" t-if="self.flags.display_title !== false">
- <t t-if="self.flags.display_title !== false" t-esc="self.action.name"/>
- </h2>
</t>
<t t-jquery=".oe-view-manager-header" t-operation="after">
<ul class="oe-view-manager-logs"></ul>
@@ -473,8 +473,6 @@
<h2><t t-esc="name"/></h2>
</div>
</t>
-
-
<t t-name="Sidebar.section.items">
<li t-foreach="items" t-as="item" t-att-class="item.classname">
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
@@ -551,6 +549,7 @@
</span>
</td>
</tr>
+
<table t-name="ListView" class="oe-listview-content">
<t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
<thead class="ui-widget-header">
@@ -568,21 +567,7 @@
Delete
</button>
</td>
- <th t-if="options.pager !== false" class="oe-list-pager">
- <button type="button" disabled="disabled"
- data-pager-action="first">First</button>
- <button type="button" disabled="disabled"
- data-pager-action="previous"
- >&lt;</button>
-
- <span class="oe-pager-state">
- </span>
-
- <button type="button" disabled="disabled"
- data-pager-action="next">&gt;</button>
- <button type="button" disabled="disabled"
- data-pager-action="last">Last</button>
- </th>
+ <t t-call="Listview.navigation.button"/>
</tr>
</table>
</th>
@@ -593,7 +578,8 @@
<t t-esc="column.string"/>
</th>
</t>
- <th t-if="options.selectable" width="1"/>
+ <th t-if="options.selectable" width="1" >
+ <input type="checkbox" class="all-record-selector"/> </th>
<t t-foreach="columns" t-as="column">
<th t-if="!column.meta and column.invisible !== '1'" t-att-data-id="column.id"
t-att-class="((options.sortable and column.tag !== 'button') ? 'oe-sortable' : null)">
@@ -612,8 +598,26 @@
</td>
<td t-if="options.deletable"/>
</tr>
+ <tr>
+ <t t-call="Listview.navigation.button"/>
+ </tr>
</tfoot>
</table>
+<th t-name="Listview.navigation.button" t-if="options.pager !== false"
+ class="oe-list-pager" t-att-colspan="columns_count">
+ <button type="button" disabled="disabled"
+ data-pager-action="first">First</button>
+ <button type="button" disabled="disabled"
+ data-pager-action="previous">&lt;</button>
+
+ <span class="oe-pager-state">
+ </span>
+
+ <button type="button" disabled="disabled"
+ data-pager-action="next">&gt;</button>
+ <button type="button" disabled="disabled"
+ data-pager-action="last">Last</button>
+</th>
<t t-name="ListView.rows" t-foreach="records.length" t-as="index">
<t t-call="ListView.row">
<t t-set="record" t-value="records.at(index)"/>
@@ -628,9 +632,18 @@
</td>
</t>
- <th t-if="options.selectable" class="oe-record-selector" width="1">
- <input type="checkbox"/>
- </th>
+ <t t-if="options.radio">
+ <th t-if="options.selectable" class="oe-record-selector" width="1">
+ <input type="radio" name ="radiogroup"/>
+ </th>
+ </t>
+ <t t-if="!options.radio">
+ <th t-if="options.selectable" class="oe-record-selector" width="1">
+ <input type="checkbox"/>
+ </th>
+ </t>
+
+
<t t-foreach="columns" t-as="column">
<t t-set="align" t-value="column.type === 'integer' or column.type == 'float'"/>
<td t-if="!column.meta and column.invisible !== '1'" t-att-title="column.help"
@@ -646,18 +659,20 @@
<t t-name="ListView.row.form">
<t t-raw="frame.render()"/>
</t>
+
<t t-name="FormView">
<div class="oe_form_header">
- <div class="oe_form_buttons" t-if="view.options.action_buttons !== false">
- <button type="button" class="oe_form_button_save">
- <span class="oe_form_on_update">Save</span>
- <span class="oe_form_on_create">Create</span>
+ <div class="oe_form_buttons" t-if="widget.options.action_buttons !== false">
+ <button type="button" class="oe_form_button_save oe_form_on_editable">Save</button>
+ <button type="button" class="oe_form_button_toggle">
+ <span class="oe_form_on_editable">Cancel</span>
+ <span class="oe_form_on_readonly">Edit</span>
</button>
- <button type="button" class="oe_form_button_new">New</button>
- <button type="button" class="oe_form_button_duplicate oe_form_on_update">Duplicate</button>
- <button type="button" class="oe_form_button_toggle">Readonly/Editable</button>
+ <button type="button" class="oe_form_button_new oe_form_on_readonly">Create</button>
+ <button type="button" class="oe_form_button_duplicate oe_form_on_readonly">Duplicate</button>
+ <button type="button" class="oe_form_button_delete oe_form_on_readonly">Delete</button>
</div>
- <div class="oe_form_pager" t-if="view.options.pager !== false">
+ <div class="oe_form_pager" t-if="widget.options.pager !== false">
<button type="button" data-pager-action="first">First</button>
<button type="button" data-pager-action="previous">&lt;&lt;</button>
@@ -740,12 +755,6 @@
<t t-call="WidgetFrame"/>
</div>
</t>
-<t t-name="WidgetNotebook.readonly">
- <t t-foreach="widget.pages" t-as="page">
- <h3><t t-esc="page.string"/></h3>
- <t t-raw="page.render()"/>
- </t>
-</t>
<t t-name="WidgetSeparator">
<div t-if="widget.orientation !== 'vertical'" t-att-class="'separator ' + widget.orientation">
<t t-esc="widget.string"/>
@@ -753,7 +762,7 @@
</t>
<t t-name="WidgetLabel">
<label t-att-for="widget.element_id"
- t-att-class="'oe_label' + (widget.help ? '_help' : '')"
+ t-attf-class="oe_label#{widget.help ? '_help' : ''} oe_align_#{widget.align}"
t-att-title="widget.help">
<t t-esc="widget.string"/>
<span t-if="widget.help">?</span>
@@ -761,10 +770,10 @@
</label>
</t>
<t t-name="WidgetParagraph">
- <p class="oe_form_paragraph"><t t-esc="widget.string"/></p>
+ <p t-attf-class="oe_form_paragraph oe_align_#{widget.align}"><t t-esc="widget.string"/></p>
</t>
<t t-name="FieldChar">
- <input type="text" size="1"
+ <input t-att-type="widget.password ? 'password' : 'text'" size="1"
t-att-name="widget.name"
t-att-id="widget.element_id"
t-attf-class="field_#{widget.type}"
@@ -855,9 +864,9 @@
</t>
<t t-name="FieldMany2One.context_menu">
<ul>
- <li t-att-id="widget.cm_id + '_open'" style="color:grey">Open...</li>
- <li t-att-id="widget.cm_id + '_create'">Create...</li>
- <li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_mandatory">Search...</li>
+ <li t-att-id="widget.cm_id + '_open'" style="color:grey" class="oe_m2o_menu_item_mandatory">Open...</li>
+ <li t-att-id="widget.cm_id + '_create'" class="oe_m2o_menu_item_noreadonly">Create...</li>
+ <li t-att-id="widget.cm_id + '_search'" class="oe_m2o_menu_item_noreadonly">Search...</li>
<t t-set="i" t-value="0"/>
<t t-foreach="widget.related_entries" t-as="entry">
<li t-att-id="widget.cm_id + '_related_' + i" style="color:grey" class="oe_m2o_menu_item_mandatory">
@@ -1002,6 +1011,7 @@
<span t-if="widget.string"><t t-esc="widget.string"/></span>
</button>
</t>
+
<t t-name="SearchView">
<form class="oe_forms">
<t t-call="SearchView.render_lines"/>
@@ -1271,6 +1281,55 @@
.unwrap();
</t>
</t>
+<t t-name="view_editor">
+ <table class="oe_view_editor">
+ <t t-call="view_editor.row"/>
+ </table>
+</t>
+<tr t-name="view_editor.row" class="oe_view_editor_row" t-att-id="'viewedit-' + rec.id" t-att-level="rec.level" t-foreach="data" t-as="rec">
+ <td class="oe_view_editor_colum" width="85%">
+ <table class="oe_view_editor_tree_grid">
+ <tr>
+ <td width="16px" t-att-style="'background-position: ' + 20*rec.level + 'px; padding-left: ' + 20*rec.level + 'px'">
+ <img t-if="rec.child_id.length" t-att-id="'parentimg-' + rec.id"
+ src="/web/static/src/img/collapse.gif" width="16" height="16" border="0"/>
+ </td>
+ <td style="cursor: pointer;">
+ <a style="text-decoration:none" href="javascript:void(0);"> <t t-esc="rec.name"/> </a>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <td align="left" class="oe_view_editor_colum" width="15%">
+ <table width="100%">
+ <tr>
+ <td width="20%">
+ <img t-if="rec.att_list.length"
+ id="side-add" src="/web/static/src/img/icons/gtk-add.png" style="cursor: pointer;"/>
+ </td>
+ <td width="20%">
+ <img id="side-remove" src="/web/static/src/img/icons/gtk-remove.png" style="cursor: pointer;"/>
+ </td>
+ <td width="20%">
+ <img t-if="rec.att_list.length"
+ id="side-edit" src="/web/static/src/img/icons/gtk-edit.png" style="cursor: pointer;"/>
+ </td>
+ <td width="20%">
+ <img t-if="rec.att_list.length"
+ id="side-up" src="/web/static/src/img/icons/gtk-go-up.png" style="cursor: pointer;"/>
+ </td>
+ <td width="20%">
+ <img t-if="rec.att_list.length"
+ id="side-down" src="/web/static/src/img/icons/gtk-go-down.png" style="cursor: pointer;"/>
+ </td>
+ </tr>
+ </table>
+ </td>
+ <t t-if="rec.child_id.length">
+ <t t-set="data" t-value="rec.child_id"/>
+ <t t-call="view_editor.row"/>
+ </t>
+</tr>
<t t-name="ExportView">
<a id="exportview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Export</a>
@@ -1405,7 +1464,8 @@
<a id="importview" href="javascript: void(0)" style="text-decoration: none;color: #3D3D3D;">Import</a>
</t>
<t t-name="ImportDataView">
-<form name="import_data" id="import_data" action="" method="post" enctype="multipart/form-data">
+<form name="import_data" id="import_data" action="" method="post" enctype="multipart/form-data"
+ class="oe-import oe-import-no-result">
<input type="hidden" name="session_id" t-att-value="session.session_id"/>
<h2 class="separator horizontal">1. Import a .CSV file</h2>
<p>Select a .CSV file to import. If you need a sample of file to import,
@@ -1415,11 +1475,11 @@
<label for="csvfile">CSV File:</label>
<input type="file" id="csvfile" size="50" name="csvfile"/>
</p>
- <h2 class="separator horizontal">2. Check your file format</h2>
- <div id="result"></div>
- <fieldset>
- <legend style="cursor:pointer;">Import Options</legend>
- <table style="display:none">
+ <h2 class="separator horizontal oe-import-result">2. Check your file format</h2>
+ <div id="result" class="oe-import-result"></div>
+ <fieldset class="oe-closed oe-import-result">
+ <legend>Import Options</legend>
+ <table>
<tr>
<td colspan="4">
<label for="file_has_headers">Does your file have titles?</label>
@@ -1449,22 +1509,24 @@
</fieldset>
</form>
</t>
-<table t-name="ImportView.result"
- class="oe_import_grid" width="100%" style="margin: 5px 0;">
- <tr t-if="headers" class="oe_import_grid-header">
- <td t-foreach="headers" t-as="header" class="oe_import_grid-cell">
- <t t-esc="header"/></td>
- </tr>
- <tr>
- <td t-foreach="records[0]" t-as="column">
- <input class="sel_fields"/>
- </td>
- </tr>
- <tr t-foreach="records" t-as="record" class="oe_import_grid-row">
- <td t-foreach="record" t-as="cell" class="oe_import_grid-cell">
- <t t-esc="cell"/></td>
- </tr>
-</table>
+<t t-name="ImportView.result">
+ <table class="oe_import_grid" width="100%" style="margin: 5px 0;">
+ <tr t-if="headers" class="oe_import_grid-header">
+ <td t-foreach="headers" t-as="header" class="oe_import_grid-cell">
+ <t t-esc="header"/></td>
+ </tr>
+ <tr>
+ <td t-foreach="records[0]" t-as="column">
+ <input class="sel_fields" placeholder="--- Don't Import ---"/><span class="oe-m2o-drop-down-button">
+ <img src="/web/static/src/img/down-arrow.png" /></span>
+ </td>
+ </tr>
+ <tr t-foreach="records" t-as="record" class="oe_import_grid-row">
+ <td t-foreach="record" t-as="cell" class="oe_import_grid-cell">
+ <t t-esc="cell"/></td>
+ </tr>
+ </table>
+</t>
<t t-name="ImportView.error">
<p style="white-space:pre-line;">The import failed due to:<t t-esc="error.message"/></p>
<t t-if="error.preview">
diff --git a/addons/web/static/test/formats.js b/addons/web/static/test/formats.js
index 3c3c6b06e72..8fc5abed42e 100644
--- a/addons/web/static/test/formats.js
+++ b/addons/web/static/test/formats.js
@@ -39,6 +39,8 @@ $(document).ready(function () {
'1.000000');
equal(openerp.web.format_value(1, {type: 'float'}),
'1.00');
+ equal(openerp.web.format_value(-11.25, {type: 'float'}),
+ "-11.25");
});
test("parse_datetime", function () {
var val = openerp.web.str_to_datetime("2009-05-04 12:34:23");
diff --git a/addons/web_calendar/__openerp__.py b/addons/web_calendar/__openerp__.py
index 1eba26065f5..5b09e70cba8 100644
--- a/addons/web_calendar/__openerp__.py
+++ b/addons/web_calendar/__openerp__.py
@@ -11,5 +11,8 @@
"css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css',
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_ext.css'
],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
'active': True
}
diff --git a/addons/web_calendar/po/ar.po b/addons/web_calendar/po/ar.po
new file mode 100644
index 00000000000..33e04220c2c
--- /dev/null
+++ b/addons/web_calendar/po/ar.po
@@ -0,0 +1,22 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:38+0200\n"
+"PO-Revision-Date: 2011-11-03 15:02+0000\n"
+"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_calendar/static/src/xml/web_calendar.xml:0
+msgid "&nbsp;"
+msgstr "&nbsp;"
diff --git a/addons/web_calendar/po/da.po b/addons/web_calendar/po/da.po
index a064b4cdc1f..68e2b21a673 100644
--- a/addons/web_calendar/po/da.po
+++ b/addons/web_calendar/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
-"X-Generator: Launchpad (build 14124)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/de.po b/addons/web_calendar/po/de.po
index c0719196cb2..27e0168a44e 100644
--- a/addons/web_calendar/po/de.po
+++ b/addons/web_calendar/po/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/es.po b/addons/web_calendar/po/es.po
index 25e6c8c24d6..9e0c5f32f98 100644
--- a/addons/web_calendar/po/es.po
+++ b/addons/web_calendar/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/es_EC.po b/addons/web_calendar/po/es_EC.po
index 2aea3aa063f..6b9cf2145dd 100644
--- a/addons/web_calendar/po/es_EC.po
+++ b/addons/web_calendar/po/es_EC.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/et.po b/addons/web_calendar/po/et.po
index f9086495da6..b08c52fbfc7 100644
--- a/addons/web_calendar/po/et.po
+++ b/addons/web_calendar/po/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/fr.po b/addons/web_calendar/po/fr.po
index 7679850c593..5f04d2d7182 100644
--- a/addons/web_calendar/po/fr.po
+++ b/addons/web_calendar/po/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/gl.po b/addons/web_calendar/po/gl.po
index 73ecf153937..7705a7cda2f 100644
--- a/addons/web_calendar/po/gl.po
+++ b/addons/web_calendar/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/it.po b/addons/web_calendar/po/it.po
index 29bbe86b507..5b98572ab45 100644
--- a/addons/web_calendar/po/it.po
+++ b/addons/web_calendar/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/nl_BE.po b/addons/web_calendar/po/nl_BE.po
index ecb2d565787..b071632ea47 100644
--- a/addons/web_calendar/po/nl_BE.po
+++ b/addons/web_calendar/po/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/sk.po b/addons/web_calendar/po/sk.po
index 168ca1d2adf..f879c6b13f1 100644
--- a/addons/web_calendar/po/sk.po
+++ b/addons/web_calendar/po/sk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/po/sl.po b/addons/web_calendar/po/sl.po
index 40f8f43a756..80c32b8728b 100644
--- a/addons/web_calendar/po/sl.po
+++ b/addons/web_calendar/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
diff --git a/addons/web_calendar/static/src/js/calendar.js b/addons/web_calendar/static/src/js/calendar.js
index a5fd8bcac9c..982fc60e1c4 100644
--- a/addons/web_calendar/static/src/js/calendar.js
+++ b/addons/web_calendar/static/src/js/calendar.js
@@ -5,7 +5,6 @@
openerp.web_calendar = function(openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
openerp.web_calendar.CalendarView = openerp.web.View.extend({
// Dhtmlx scheduler ?
diff --git a/addons/web_dashboard/__openerp__.py b/addons/web_dashboard/__openerp__.py
index 7a527511b03..68c73731c71 100644
--- a/addons/web_dashboard/__openerp__.py
+++ b/addons/web_dashboard/__openerp__.py
@@ -7,5 +7,8 @@
'static/src/js/dashboard.js'
],
"css": ['static/src/css/dashboard.css'],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
'active': True
}
diff --git a/addons/web_dashboard/po/ar.po b/addons/web_dashboard/po/ar.po
new file mode 100644
index 00000000000..0e2cf4dfcf2
--- /dev/null
+++ b/addons/web_dashboard/po/ar.po
@@ -0,0 +1,46 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-03 15:09+0000\n"
+"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Reset"
+msgstr "إستعادة"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Undo"
+msgstr "تراجع"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Add Widget"
+msgstr "أضف أداة"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Change layout"
+msgstr "تغيير المخطط"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Choose dashboard layout"
+msgstr "اختر مخطط للعرض"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "progress:"
+msgstr "التقدم:"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "%"
+msgstr "%"
diff --git a/addons/web_dashboard/po/da.po b/addons/web_dashboard/po/da.po
index 8df0abb1499..312ceaa7327 100644
--- a/addons/web_dashboard/po/da.po
+++ b/addons/web_dashboard/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
-"X-Generator: Launchpad (build 14124)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/de.po b/addons/web_dashboard/po/de.po
index 6e2b8e003a3..1fecf9c9550 100644
--- a/addons/web_dashboard/po/de.po
+++ b/addons/web_dashboard/po/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/es.po b/addons/web_dashboard/po/es.po
index 8cd91812416..9686bc1b517 100644
--- a/addons/web_dashboard/po/es.po
+++ b/addons/web_dashboard/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/es_EC.po b/addons/web_dashboard/po/es_EC.po
index 11cf8918d7f..24ae8287a6d 100644
--- a/addons/web_dashboard/po/es_EC.po
+++ b/addons/web_dashboard/po/es_EC.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/et.po b/addons/web_dashboard/po/et.po
index 381db624021..06fccba4842 100644
--- a/addons/web_dashboard/po/et.po
+++ b/addons/web_dashboard/po/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/fr.po b/addons/web_dashboard/po/fr.po
index b02d061cdd2..a8c0e7ba530 100644
--- a/addons/web_dashboard/po/fr.po
+++ b/addons/web_dashboard/po/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/gl.po b/addons/web_dashboard/po/gl.po
index b7a081aff6f..16edea4823f 100644
--- a/addons/web_dashboard/po/gl.po
+++ b/addons/web_dashboard/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/it.po b/addons/web_dashboard/po/it.po
index 2986cb8ccd0..90e98cd48bc 100644
--- a/addons/web_dashboard/po/it.po
+++ b/addons/web_dashboard/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/nl_BE.po b/addons/web_dashboard/po/nl_BE.po
index 40dcc0438a7..57a9fdadbf5 100644
--- a/addons/web_dashboard/po/nl_BE.po
+++ b/addons/web_dashboard/po/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/pl.po b/addons/web_dashboard/po/pl.po
new file mode 100644
index 00000000000..256945c9030
--- /dev/null
+++ b/addons/web_dashboard/po/pl.po
@@ -0,0 +1,46 @@
+# Polish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-04 16:28+0000\n"
+"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Reset"
+msgstr "Przywróć"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Undo"
+msgstr "Cofnij"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Add Widget"
+msgstr "Dodaj kontrolkę"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Change layout"
+msgstr "Zmień układ"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "Choose dashboard layout"
+msgstr "Wybierz układ konsoli"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "progress:"
+msgstr "postęp:"
+
+#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
+msgid "%"
+msgstr ""
diff --git a/addons/web_dashboard/po/sk.po b/addons/web_dashboard/po/sk.po
index d2c2b2160a0..a9e11093ef1 100644
--- a/addons/web_dashboard/po/sk.po
+++ b/addons/web_dashboard/po/sk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/po/sl.po b/addons/web_dashboard/po/sl.po
index 9eee401c427..01a5bf45deb 100644
--- a/addons/web_dashboard/po/sl.po
+++ b/addons/web_dashboard/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js
index 923b43ce034..e629a4a6ef5 100644
--- a/addons/web_dashboard/static/src/js/dashboard.js
+++ b/addons/web_dashboard/static/src/js/dashboard.js
@@ -1,6 +1,5 @@
openerp.web_dashboard = function(openerp) {
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
if (!openerp.web_dashboard) {
/** @namespace */
@@ -468,7 +467,7 @@ openerp.web_dashboard.ApplicationTiles = openerp.web.View.extend({
[['name', '=', module_name], ['state', '=', 'uninstalled']]);
var Upgrade = new openerp.web.DataSet(this, 'base.module.upgrade');
- $.blockUI({message:'<img src="/web/static/src/img/throbber2.gif">'});
+ $.blockUI();
Modules.read_slice(['id'], {}, function (records) {
if (!(records.length === 1)) { $.unblockUI(); return; }
Modules.call('state_update',
diff --git a/addons/web_dashboard/static/src/xml/web_dashboard.xml b/addons/web_dashboard/static/src/xml/web_dashboard.xml
index 87222baa5fd..77eab4b7e28 100644
--- a/addons/web_dashboard/static/src/xml/web_dashboard.xml
+++ b/addons/web_dashboard/static/src/xml/web_dashboard.xml
@@ -30,7 +30,7 @@
</t>
<t t-name="DashBoard.action">
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
- <h2 t-attf-class="oe-dashboard-action-header oe_view_title #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
+ <h2 t-attf-class="oe-dashboard-action-header #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
<t t-esc="action.attrs.string"/>
<t t-if="!action.attrs.string">&amp;nbsp;</t>
diff --git a/addons/web_default_home/po/ar.po b/addons/web_default_home/po/ar.po
new file mode 100644
index 00000000000..48260328d70
--- /dev/null
+++ b/addons/web_default_home/po/ar.po
@@ -0,0 +1,38 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-08 05:50+0000\n"
+"Last-Translator: Ahmad Khayyat <Unknown>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-08 06:12+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "أهلاً و مرحباً بك في OpenERP"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "لا تنس إدراج هذه الصفحة ضمن المفضلات"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "تذكر كلمة المرور"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "اختر أول تطبيق OpenERP تود تثبيته"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "تثبيت"
diff --git a/addons/web_default_home/po/da.po b/addons/web_default_home/po/da.po
new file mode 100644
index 00000000000..989daa78361
--- /dev/null
+++ b/addons/web_default_home/po/da.po
@@ -0,0 +1,38 @@
+# Danish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-11 14:02+0000\n"
+"Last-Translator: Jonas Mortensen <Unknown>\n"
+"Language-Team: Danish <da@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Velkommen til din nye OpenERP instans."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Husk at tilføje denne side til dine favoritter."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Husk dit log ind:"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Vælg den første OpenERP Applikation som du ønsker at installere."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Installér"
diff --git a/addons/web_default_home/po/de.po b/addons/web_default_home/po/de.po
new file mode 100644
index 00000000000..2363aea8505
--- /dev/null
+++ b/addons/web_default_home/po/de.po
@@ -0,0 +1,38 @@
+# German translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-10 12:40+0000\n"
+"Last-Translator: Felix Schubert <Unknown>\n"
+"Language-Team: German <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Willkommen zu Ihrer neuen OpenERP Instanz."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Denken Sie daran ein Lesezeichen für diese Seite zu setzen."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Anmeldung speichern"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Wählen Sie die erste OpenERP Anwendung die Sie installieren möchten."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Installieren"
diff --git a/addons/web_default_home/po/es.po b/addons/web_default_home/po/es.po
index 4f35e5b6345..5120f12015d 100644
--- a/addons/web_default_home/po/es.po
+++ b/addons/web_default_home/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
diff --git a/addons/web_default_home/po/es_EC.po b/addons/web_default_home/po/es_EC.po
new file mode 100644
index 00000000000..077b51cbeee
--- /dev/null
+++ b/addons/web_default_home/po/es_EC.po
@@ -0,0 +1,38 @@
+# Spanish (Ecuador) translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-07 16:00+0000\n"
+"Last-Translator: Cristian Salamea (Gnuthink) <ovnicraft@gmail.com>\n"
+"Language-Team: Spanish (Ecuador) <es_EC@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Bienvenido a tu nueva instancia de OpenERP"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Recuerda marcar esta página"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Recordar tu inicio de sesión"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Escoge la primea Aplicación OpenERP que deseas instalar..."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Instalar"
diff --git a/addons/web_default_home/po/et.po b/addons/web_default_home/po/et.po
new file mode 100644
index 00000000000..a2dedb192d4
--- /dev/null
+++ b/addons/web_default_home/po/et.po
@@ -0,0 +1,38 @@
+# Estonian translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-10 19:29+0000\n"
+"Last-Translator: Aare Vesi <Unknown>\n"
+"Language-Team: Estonian <et@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Paigalda"
diff --git a/addons/web_default_home/po/fr.po b/addons/web_default_home/po/fr.po
index ec8855f86cf..e1b15ca7021 100644
--- a/addons/web_default_home/po/fr.po
+++ b/addons/web_default_home/po/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
diff --git a/addons/web_default_home/po/gl.po b/addons/web_default_home/po/gl.po
index 4069197dec9..5783af8a2fb 100644
--- a/addons/web_default_home/po/gl.po
+++ b/addons/web_default_home/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
diff --git a/addons/web_default_home/po/it.po b/addons/web_default_home/po/it.po
new file mode 100644
index 00000000000..a9f3a86854b
--- /dev/null
+++ b/addons/web_default_home/po/it.po
@@ -0,0 +1,38 @@
+# Italian translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-08 13:41+0000\n"
+"Last-Translator: Nicola Riolini - Micronaet <Unknown>\n"
+"Language-Team: Italian <it@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Benvenuto nella nuova istanza di OpenERP"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Ricordarsi di aggiungere ai preferiti questa pagina"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Ricordare il proprio login:"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Scegliere la prima applicazione OpenERP che volete installare..."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Installa"
diff --git a/addons/web_default_home/po/nl_BE.po b/addons/web_default_home/po/nl_BE.po
new file mode 100644
index 00000000000..1f046075120
--- /dev/null
+++ b/addons/web_default_home/po/nl_BE.po
@@ -0,0 +1,38 @@
+# Dutch (Belgium) translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-10-07 09:07+0000\n"
+"Last-Translator: Niels Huylebroeck <Unknown>\n"
+"Language-Team: Dutch (Belgium) <nl_BE@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Welkom bij uw nieuwe OpenERP."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Gelieve een bookmark voor deze pagina te maken."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Vergeet je login niet:"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Kies welke OpenERP Applicatie je wilt installeren..."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Installeer"
diff --git a/addons/web_default_home/po/pl.po b/addons/web_default_home/po/pl.po
new file mode 100644
index 00000000000..3eec2b0ab49
--- /dev/null
+++ b/addons/web_default_home/po/pl.po
@@ -0,0 +1,38 @@
+# Polish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-04 16:30+0000\n"
+"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr "Witamy w twojej nowej instancji OpenERP."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr "Pamiętaj o dodaniu tej strony do zakładek."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr "Zapamiętaj twój login:"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr "Wybierz pierwszą aplikację OpenERP do instalacji."
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr "Instaluj"
diff --git a/addons/web_default_home/po/sk.po b/addons/web_default_home/po/sk.po
new file mode 100644
index 00000000000..bf766fb65b0
--- /dev/null
+++ b/addons/web_default_home/po/sk.po
@@ -0,0 +1,38 @@
+# Slovak translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-01 13:27+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Slovak <sk@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-02 05:05+0000\n"
+"X-Generator: Launchpad (build 14214)\n"
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Welcome to your new OpenERP instance."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember to bookmark this page."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Remember your login:"
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Choose the first OpenERP Application you want to install.."
+msgstr ""
+
+#: addons/web_default_home/static/src/xml/web_default_home.xml:0
+msgid "Install"
+msgstr ""
diff --git a/addons/web_default_home/po/sl.po b/addons/web_default_home/po/sl.po
index d9f10a9e92f..2f9d918cb49 100644
--- a/addons/web_default_home/po/sl.po
+++ b/addons/web_default_home/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
diff --git a/addons/web_diagram/__openerp__.py b/addons/web_diagram/__openerp__.py
index 584c0a16e66..cd9eb719934 100644
--- a/addons/web_diagram/__openerp__.py
+++ b/addons/web_diagram/__openerp__.py
@@ -13,5 +13,8 @@
'css' : [
"static/src/css/base_diagram.css",
],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
'active': True,
}
diff --git a/addons/web_diagram/controllers/main.py b/addons/web_diagram/controllers/main.py
index 51861c17b5f..55047804725 100644
--- a/addons/web_diagram/controllers/main.py
+++ b/addons/web_diagram/controllers/main.py
@@ -93,7 +93,6 @@ class DiagramView(View):
n.update(
id=act['id'],
color='white',
- shape='ellipse',
options={}
)
for color, expr in bgcolors.items():
@@ -107,12 +106,5 @@ class DiagramView(View):
for i, fld in enumerate(visible_node_fields):
n['options'][node_fields_string[i]] = act[fld]
- #to relate m2o field of transition to corresponding o2m in activity
- in_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', des_node), ('model', '=', node)], 0, 0, 0, req.session.context)
- in_transition_field = fields.read(in_transition_field_id[0], ['name'], req.session.context)['name']
-
- out_transition_field_id = fields.search([('relation', '=', connector), ('relation_field', '=', src_node), ('model', '=', node)], 0, 0, 0, req.session.context)
- out_transition_field = fields.read(out_transition_field_id[0], ['name'], req.session.context)['name']
-
id_model = req.session.model(model).read([id],['name'], req.session.context)[0]['name']
- return dict(nodes=nodes, conn=connectors, id_model = id_model)
+ return dict(nodes=nodes, conn=connectors, id_model=id_model)
diff --git a/addons/web_diagram/po/ar.po b/addons/web_diagram/po/ar.po
new file mode 100644
index 00000000000..af8c6ab7213
--- /dev/null
+++ b/addons/web_diagram/po/ar.po
@@ -0,0 +1,54 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-03 15:11+0000\n"
+"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "New Node"
+msgstr "طرف جديد"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "New Edge"
+msgstr "حافة جديدة"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "Show Grid:"
+msgstr "عرض الشبكة"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "First"
+msgstr "الأول"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "<<"
+msgstr ">>"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "0"
+msgstr "0"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "/"
+msgstr "/"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid ">>"
+msgstr ">>"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "Last"
+msgstr "الأخير"
diff --git a/addons/web_diagram/po/da.po b/addons/web_diagram/po/da.po
index e91754b6da3..b0a68cf641c 100644
--- a/addons/web_diagram/po/da.po
+++ b/addons/web_diagram/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
-"X-Generator: Launchpad (build 14124)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/de.po b/addons/web_diagram/po/de.po
index 2aa5e23eb13..1a511d763ba 100644
--- a/addons/web_diagram/po/de.po
+++ b/addons/web_diagram/po/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/es.po b/addons/web_diagram/po/es.po
index 192c69b6428..465cc16f401 100644
--- a/addons/web_diagram/po/es.po
+++ b/addons/web_diagram/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/es_EC.po b/addons/web_diagram/po/es_EC.po
index 0aff9dc73a0..3faa86e9bc5 100644
--- a/addons/web_diagram/po/es_EC.po
+++ b/addons/web_diagram/po/es_EC.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/et.po b/addons/web_diagram/po/et.po
index f2f3816fafa..5f8e394d816 100644
--- a/addons/web_diagram/po/et.po
+++ b/addons/web_diagram/po/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/gl.po b/addons/web_diagram/po/gl.po
index 0aca25055d3..27f4dc017fa 100644
--- a/addons/web_diagram/po/gl.po
+++ b/addons/web_diagram/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/it.po b/addons/web_diagram/po/it.po
index f9ab13eaec5..c3ced470ca6 100644
--- a/addons/web_diagram/po/it.po
+++ b/addons/web_diagram/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/nl_BE.po b/addons/web_diagram/po/nl_BE.po
index 6f574501bba..4d2999c099d 100644
--- a/addons/web_diagram/po/nl_BE.po
+++ b/addons/web_diagram/po/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/po/pl.po b/addons/web_diagram/po/pl.po
new file mode 100644
index 00000000000..f36f3853850
--- /dev/null
+++ b/addons/web_diagram/po/pl.po
@@ -0,0 +1,54 @@
+# Polish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-04 16:24+0000\n"
+"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "New Node"
+msgstr "Nowy węzeł"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "New Edge"
+msgstr "Nowa linia"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "Show Grid:"
+msgstr "Pokaż siatkę"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "First"
+msgstr "Pierwsze"
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "<<"
+msgstr ""
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "0"
+msgstr ""
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "/"
+msgstr ""
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid ">>"
+msgstr ""
+
+#: addons/web_diagram/static/src/xml/base_diagram.xml:0
+msgid "Last"
+msgstr "Ostatnie"
diff --git a/addons/web_diagram/po/sl.po b/addons/web_diagram/po/sl.po
index 9cce3a3564e..6766b54fb3c 100644
--- a/addons/web_diagram/po/sl.po
+++ b/addons/web_diagram/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
diff --git a/addons/web_diagram/static/lib/js/dracula_graffle.js b/addons/web_diagram/static/lib/js/dracula_graffle.js
index 9d4fd2099e8..2b03ad16c79 100644
--- a/addons/web_diagram/static/lib/js/dracula_graffle.js
+++ b/addons/web_diagram/static/lib/js/dracula_graffle.js
@@ -71,7 +71,7 @@ Raphael.fn.connection = function (obj1, obj2, style) {
x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3),
y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3);
/* assemble path and arrow */
- var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(",");
+ var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)];
/* arrow */
if(style && style.directed) {
/* magnitude, length of the last path vector */
@@ -83,15 +83,16 @@ Raphael.fn.connection = function (obj1, obj2, style) {
{x:(norm(x4-x3)+norm(y4-y3)+x4).toFixed(3), y:(norm(y4-y3)+norm(x4-x3)+y4).toFixed(3)},
{x:(norm(x4-x3)-norm(y4-y3)+x4).toFixed(3), y:(norm(y4-y3)-norm(x4-x3)+y4).toFixed(3)}
];
- path = path + ",M"+arr[0].x+","+arr[0].y+",L"+x4+","+y4+",L"+arr[1].x+","+arr[1].y;
+ path.push("M", arr[0].x, arr[0].y, "L", x4, y4, "L", arr[1].x, arr[1].y, "L", arr[0].x, arr[0].y);
}
+ var svgpath = path.join(' ');
/* function to be used for moving existent path(s), e.g. animate() or attr() */
var move = "attr";
/* applying path(s) */
- edge.fg && edge.fg[move]({path:path})
- || (edge.fg = selfRef.path(path).attr({stroke: style && style.stroke || "#000", fill: "none"}).toBack());
- edge.bg && edge.bg[move]({path:path})
- || style && style.fill && (edge.bg = style.fill.split && selfRef.path(path).attr({stroke: style.fill.split("|")[0], fill: "none", "stroke-width": style.fill.split("|")[1] || 3}).toBack());
+ edge.fg && edge.fg[move]({path:svgpath})
+ || (edge.fg = selfRef.path(svgpath).attr({stroke: style && style.stroke || "#000", fill: "none"}).toBack());
+ edge.bg && edge.bg[move]({path:svgpath})
+ || style && style.fill && (edge.bg = style.fill.split && selfRef.path(svgpath).attr({stroke: style.fill.split("|")[0], fill: "none", "stroke-width": style.fill.split("|")[1] || 3}).toBack());
/* setting label */
style && style.label
&& (edge.label && edge.label.attr({x:(x1+x4)/2, y:(y1+y4)/2})
diff --git a/addons/web_diagram/static/lib/js/dracula_graph.js b/addons/web_diagram/static/lib/js/dracula_graph.js
index df9945882a7..28269986e78 100644
--- a/addons/web_diagram/static/lib/js/dracula_graph.js
+++ b/addons/web_diagram/static/lib/js/dracula_graph.js
@@ -160,13 +160,11 @@ Graph.Renderer.Raphael = function(element, graph, width, height) {
*/
this.isDrag = false;
this.dragger = function (e) {
- if(e.detail < 2) {
- this.dx = e.clientX;
- this.dy = e.clientY;
- selfRef.isDrag = this;
- this.set && this.set.animate({"fill-opacity": .1}, 200) && this.set.toFront();
- e.preventDefault && e.preventDefault();
- }
+ this.dx = e.clientX;
+ this.dy = e.clientY;
+ selfRef.isDrag = this;
+ this.set && this.set.animate({"fill-opacity": .1}, 200);
+ e.preventDefault && e.preventDefault();
};
var d = document.getElementById(element);
@@ -378,6 +376,8 @@ Graph.Layout.Spring.prototype = {
},
layoutRepulsive: function(node1, node2) {
+ if (typeof node1 == 'undefined' || typeof node2 == 'undefined')
+ return;
var dx = node2.layoutPosX - node1.layoutPosX;
var dy = node2.layoutPosY - node1.layoutPosY;
var d2 = dx * dx + dy * dy;
diff --git a/addons/web_diagram/static/lib/js/raphael-min.js b/addons/web_diagram/static/lib/js/raphael-min.js
index 8718b5bc749..e69ea16a809 100644
--- a/addons/web_diagram/static/lib/js/raphael-min.js
+++ b/addons/web_diagram/static/lib/js/raphael-min.js
@@ -1,7 +1,8 @@
-/*
- * Raphael 1.3.1 - JavaScript Vector Library
- *
- * Copyright (c) 2008 - 2009 Dmitry Baranovskiy (http://raphaeljs.com)
- * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
- */
-Raphael=(function(){var a=/[, ]+/,aO=/^(circle|rect|path|ellipse|text|image)$/,L=document,au=window,l={was:"Raphael" in au,is:au.Raphael},an=function(){if(an.is(arguments[0],"array")){var d=arguments[0],e=w[aW](an,d.splice(0,3+an.is(d[0],al))),S=e.set();for(var R=0,a0=d[m];R<a0;R++){var E=d[R]||{};aO.test(E.type)&&S[f](e[E.type]().attr(E));}return S;}return w[aW](an,arguments);},aT=function(){},aL="appendChild",aW="apply",aS="concat",at="",am=" ",z="split",F="click dblclick mousedown mousemove mouseout mouseover mouseup"[z](am),Q="hasOwnProperty",az="join",m="length",aY="prototype",aZ=String[aY].toLowerCase,ab=Math,g=ab.max,aI=ab.min,al="number",aA="toString",aw=Object[aY][aA],aQ={},aM=ab.pow,f="push",aU=/^(?=[\da-f]$)/,c=/^url\(['"]?([^\)]+)['"]?\)$/i,x=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgb\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|rgb\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\)|hs[bl]\(\s*([\d\.]+\s*,\s*[\d\.]+\s*,\s*[\d\.]+)\s*\)|hs[bl]\(\s*([\d\.]+%\s*,\s*[\d\.]+%\s*,\s*[\d\.]+%)\s*\))\s*$/i,O=ab.round,v="setAttribute",W=parseFloat,G=parseInt,aN=String[aY].toUpperCase,j={"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rotation:0,rx:0,ry:0,scale:"1 1",src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",translation:"0 0",width:0,x:0,y:0},Z={along:"along","clip-rect":"csv",cx:al,cy:al,fill:"colour","fill-opacity":al,"font-size":al,height:al,opacity:al,path:"path",r:al,rotation:"csv",rx:al,ry:al,scale:"csv",stroke:"colour","stroke-opacity":al,"stroke-width":al,translation:"csv",width:al,x:al,y:al},aP="replace";an.version="1.3.1";an.type=(au.SVGAngle||L.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML");if(an.type=="VML"){var ag=document.createElement("div");ag.innerHTML="<!--[if vml]><br><br><![endif]-->";if(ag.childNodes[m]!=2){return null;}}an.svg=!(an.vml=an.type=="VML");aT[aY]=an[aY];an._id=0;an._oid=0;an.fn={};an.is=function(e,d){d=aZ.call(d);return((d=="object"||d=="undefined")&&typeof e==d)||(e==null&&d=="null")||aZ.call(aw.call(e).slice(8,-1))==d;};an.setWindow=function(d){au=d;L=au.document;};var aD=function(e){if(an.vml){var d=/^\s+|\s+$/g;aD=aj(function(R){var S;R=(R+at)[aP](d,at);try{var a0=new ActiveXObject("htmlfile");a0.write("<body>");a0.close();S=a0.body;}catch(a2){S=createPopup().document.body;}var i=S.createTextRange();try{S.style.color=R;var a1=i.queryCommandValue("ForeColor");a1=((a1&255)<<16)|(a1&65280)|((a1&16711680)>>>16);return"#"+("000000"+a1[aA](16)).slice(-6);}catch(a2){return"none";}});}else{var E=L.createElement("i");E.title="Rapha\xebl Colour Picker";E.style.display="none";L.body[aL](E);aD=aj(function(i){E.style.color=i;return L.defaultView.getComputedStyle(E,at).getPropertyValue("color");});}return aD(e);};an.hsb2rgb=aj(function(a3,a1,a7){if(an.is(a3,"object")&&"h" in a3&&"s" in a3&&"b" in a3){a7=a3.b;a1=a3.s;a3=a3.h;}var R,S,a8;if(a7==0){return{r:0,g:0,b:0,hex:"#000"};}if(a3>1||a1>1||a7>1){a3/=255;a1/=255;a7/=255;}var a0=~~(a3*6),a4=(a3*6)-a0,E=a7*(1-a1),e=a7*(1-(a1*a4)),a9=a7*(1-(a1*(1-a4)));R=[a7,e,E,E,a9,a7,a7][a0];S=[a9,a7,a7,e,E,E,a9][a0];a8=[E,E,a9,a7,a7,e,E][a0];R*=255;S*=255;a8*=255;var a5={r:R,g:S,b:a8},d=(~~R)[aA](16),a2=(~~S)[aA](16),a6=(~~a8)[aA](16);d=d[aP](aU,"0");a2=a2[aP](aU,"0");a6=a6[aP](aU,"0");a5.hex="#"+d+a2+a6;return a5;},an);an.rgb2hsb=aj(function(d,e,a1){if(an.is(d,"object")&&"r" in d&&"g" in d&&"b" in d){a1=d.b;e=d.g;d=d.r;}if(an.is(d,"string")){var a3=an.getRGB(d);d=a3.r;e=a3.g;a1=a3.b;}if(d>1||e>1||a1>1){d/=255;e/=255;a1/=255;}var a0=g(d,e,a1),i=aI(d,e,a1),R,E,S=a0;if(i==a0){return{h:0,s:0,b:a0};}else{var a2=(a0-i);E=a2/a0;if(d==a0){R=(e-a1)/a2;}else{if(e==a0){R=2+((a1-d)/a2);}else{R=4+((d-e)/a2);}}R/=6;R<0&&R++;R>1&&R--;}return{h:R,s:E,b:S};},an);var aE=/,?([achlmqrstvxz]),?/gi;an._path2string=function(){return this.join(",")[aP](aE,"$1");};function aj(E,e,d){function i(){var R=Array[aY].slice.call(arguments,0),a0=R[az]("\u25ba"),S=i.cache=i.cache||{},a1=i.count=i.count||[];if(S[Q](a0)){return d?d(S[a0]):S[a0];}a1[m]>=1000&&delete S[a1.shift()];a1[f](a0);S[a0]=E[aW](e,R);return d?d(S[a0]):S[a0];}return i;}an.getRGB=aj(function(d){if(!d||!!((d=d+at).indexOf("-")+1)){return{r:-1,g:-1,b:-1,hex:"none",error:1};}if(d=="none"){return{r:-1,g:-1,b:-1,hex:"none"};}!(({hs:1,rg:1})[Q](d.substring(0,2))||d.charAt()=="#")&&(d=aD(d));var S,i,E,a2,a3,a0=d.match(x);if(a0){if(a0[2]){a2=G(a0[2].substring(5),16);E=G(a0[2].substring(3,5),16);i=G(a0[2].substring(1,3),16);}if(a0[3]){a2=G((a3=a0[3].charAt(3))+a3,16);E=G((a3=a0[3].charAt(2))+a3,16);i=G((a3=a0[3].charAt(1))+a3,16);}if(a0[4]){a0=a0[4][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);}if(a0[5]){a0=a0[5][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;}if(a0[6]){a0=a0[6][z](/\s*,\s*/);i=W(a0[0]);E=W(a0[1]);a2=W(a0[2]);return an.hsb2rgb(i,E,a2);}if(a0[7]){a0=a0[7][z](/\s*,\s*/);i=W(a0[0])*2.55;E=W(a0[1])*2.55;a2=W(a0[2])*2.55;return an.hsb2rgb(i,E,a2);}a0={r:i,g:E,b:a2};var e=(~~i)[aA](16),R=(~~E)[aA](16),a1=(~~a2)[aA](16);e=e[aP](aU,"0");R=R[aP](aU,"0");a1=a1[aP](aU,"0");a0.hex="#"+e+R+a1;return a0;}return{r:-1,g:-1,b:-1,hex:"none",error:1};},an);an.getColor=function(e){var i=this.getColor.start=this.getColor.start||{h:0,s:1,b:e||0.75},d=this.hsb2rgb(i.h,i.s,i.b);i.h+=0.075;if(i.h>1){i.h=0;i.s-=0.2;i.s<=0&&(this.getColor.start={h:0,s:1,b:i.b});}return d.hex;};an.getColor.reset=function(){delete this.start;};an.parsePathString=aj(function(d){if(!d){return null;}var i={a:7,c:6,h:1,l:2,m:2,q:4,s:4,t:2,v:1,z:0},e=[];if(an.is(d,"array")&&an.is(d[0],"array")){e=av(d);}if(!e[m]){(d+at)[aP](/([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig,function(R,E,a1){var a0=[],S=aZ.call(E);a1[aP](/(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig,function(a3,a2){a2&&a0[f](+a2);});while(a0[m]>=i[S]){e[f]([E][aS](a0.splice(0,i[S])));if(!i[S]){break;}}});}e[aA]=an._path2string;return e;});an.findDotsAtSegment=function(e,d,be,bc,a0,R,a2,a1,a8){var a6=1-a8,a5=aM(a6,3)*e+aM(a6,2)*3*a8*be+a6*3*a8*a8*a0+aM(a8,3)*a2,a3=aM(a6,3)*d+aM(a6,2)*3*a8*bc+a6*3*a8*a8*R+aM(a8,3)*a1,ba=e+2*a8*(be-e)+a8*a8*(a0-2*be+e),a9=d+2*a8*(bc-d)+a8*a8*(R-2*bc+d),bd=be+2*a8*(a0-be)+a8*a8*(a2-2*a0+be),bb=bc+2*a8*(R-bc)+a8*a8*(a1-2*R+bc),a7=(1-a8)*e+a8*be,a4=(1-a8)*d+a8*bc,E=(1-a8)*a0+a8*a2,i=(1-a8)*R+a8*a1,S=(90-ab.atan((ba-bd)/(a9-bb))*180/ab.PI);(ba>bd||a9<bb)&&(S+=180);return{x:a5,y:a3,m:{x:ba,y:a9},n:{x:bd,y:bb},start:{x:a7,y:a4},end:{x:E,y:i},alpha:S};};var U=aj(function(a5){if(!a5){return{x:0,y:0,width:0,height:0};}a5=H(a5);var a2=0,a1=0,R=[],e=[],E;for(var S=0,a4=a5[m];S<a4;S++){E=a5[S];if(E[0]=="M"){a2=E[1];a1=E[2];R[f](a2);e[f](a1);}else{var a0=aC(a2,a1,E[1],E[2],E[3],E[4],E[5],E[6]);R=R[aS](a0.min.x,a0.max.x);e=e[aS](a0.min.y,a0.max.y);a2=E[5];a1=E[6];}}var d=aI[aW](0,R),a3=aI[aW](0,e);return{x:d,y:a3,width:g[aW](0,R)-d,height:g[aW](0,e)-a3};}),av=function(a0){var E=[];if(!an.is(a0,"array")||!an.is(a0&&a0[0],"array")){a0=an.parsePathString(a0);}for(var e=0,R=a0[m];e<R;e++){E[e]=[];for(var d=0,S=a0[e][m];d<S;d++){E[e][d]=a0[e][d];}}E[aA]=an._path2string;return E;},ad=aj(function(R){if(!an.is(R,"array")||!an.is(R&&R[0],"array")){R=an.parsePathString(R);}var a4=[],a6=0,a5=0,a9=0,a8=0,E=0;if(R[0][0]=="M"){a6=R[0][1];a5=R[0][2];a9=a6;a8=a5;E++;a4[f](["M",a6,a5]);}for(var a1=E,ba=R[m];a1<ba;a1++){var d=a4[a1]=[],a7=R[a1];if(a7[0]!=aZ.call(a7[0])){d[0]=aZ.call(a7[0]);switch(d[0]){case"a":d[1]=a7[1];d[2]=a7[2];d[3]=a7[3];d[4]=a7[4];d[5]=a7[5];d[6]=+(a7[6]-a6).toFixed(3);d[7]=+(a7[7]-a5).toFixed(3);break;case"v":d[1]=+(a7[1]-a5).toFixed(3);break;case"m":a9=a7[1];a8=a7[2];default:for(var a0=1,a2=a7[m];a0<a2;a0++){d[a0]=+(a7[a0]-((a0%2)?a6:a5)).toFixed(3);}}}else{d=a4[a1]=[];if(a7[0]=="m"){a9=a7[1]+a6;a8=a7[2]+a5;}for(var S=0,e=a7[m];S<e;S++){a4[a1][S]=a7[S];}}var a3=a4[a1][m];switch(a4[a1][0]){case"z":a6=a9;a5=a8;break;case"h":a6+=+a4[a1][a3-1];break;case"v":a5+=+a4[a1][a3-1];break;default:a6+=+a4[a1][a3-2];a5+=+a4[a1][a3-1];}}a4[aA]=an._path2string;return a4;},0,av),r=aj(function(R){if(!an.is(R,"array")||!an.is(R&&R[0],"array")){R=an.parsePathString(R);}var a3=[],a5=0,a4=0,a8=0,a7=0,E=0;if(R[0][0]=="M"){a5=+R[0][1];a4=+R[0][2];a8=a5;a7=a4;E++;a3[0]=["M",a5,a4];}for(var a1=E,a9=R[m];a1<a9;a1++){var d=a3[a1]=[],a6=R[a1];if(a6[0]!=aN.call(a6[0])){d[0]=aN.call(a6[0]);switch(d[0]){case"A":d[1]=a6[1];d[2]=a6[2];d[3]=a6[3];d[4]=a6[4];d[5]=a6[5];d[6]=+(a6[6]+a5);d[7]=+(a6[7]+a4);break;case"V":d[1]=+a6[1]+a4;break;case"H":d[1]=+a6[1]+a5;break;case"M":a8=+a6[1]+a5;a7=+a6[2]+a4;default:for(var a0=1,a2=a6[m];a0<a2;a0++){d[a0]=+a6[a0]+((a0%2)?a5:a4);}}}else{for(var S=0,e=a6[m];S<e;S++){a3[a1][S]=a6[S];}}switch(d[0]){case"Z":a5=a8;a4=a7;break;case"H":a5=d[1];break;case"V":a4=d[1];break;default:a5=a3[a1][a3[a1][m]-2];a4=a3[a1][a3[a1][m]-1];}}a3[aA]=an._path2string;return a3;},null,av),aX=function(e,E,d,i){return[e,E,d,i,d,i];},aK=function(e,E,a0,R,d,i){var S=1/3,a1=2/3;return[S*e+a1*a0,S*E+a1*R,S*d+a1*a0,S*i+a1*R,d,i];},K=function(a9,bE,bi,bg,ba,a4,S,a8,bD,bb){var R=ab.PI,bf=R*120/180,d=R/180*(+ba||0),bm=[],bj,bA=aj(function(bF,bI,i){var bH=bF*ab.cos(i)-bI*ab.sin(i),bG=bF*ab.sin(i)+bI*ab.cos(i);return{x:bH,y:bG};});if(!bb){bj=bA(a9,bE,-d);a9=bj.x;bE=bj.y;bj=bA(a8,bD,-d);a8=bj.x;bD=bj.y;var e=ab.cos(R/180*ba),a6=ab.sin(R/180*ba),bo=(a9-a8)/2,bn=(bE-bD)/2;bi=g(bi,ab.abs(bo));bg=g(bg,ab.abs(bn));var by=(bo*bo)/(bi*bi)+(bn*bn)/(bg*bg);if(by>1){bi=ab.sqrt(by)*bi;bg=ab.sqrt(by)*bg;}var E=bi*bi,br=bg*bg,bt=(a4==S?-1:1)*ab.sqrt(ab.abs((E*br-E*bn*bn-br*bo*bo)/(E*bn*bn+br*bo*bo))),bd=bt*bi*bn/bg+(a9+a8)/2,bc=bt*-bg*bo/bi+(bE+bD)/2,a3=ab.asin(((bE-bc)/bg).toFixed(7)),a2=ab.asin(((bD-bc)/bg).toFixed(7));a3=a9<bd?R-a3:a3;a2=a8<bd?R-a2:a2;a3<0&&(a3=R*2+a3);a2<0&&(a2=R*2+a2);if(S&&a3>a2){a3=a3-R*2;}if(!S&&a2>a3){a2=a2-R*2;}}else{a3=bb[0];a2=bb[1];bd=bb[2];bc=bb[3];}var a7=a2-a3;if(ab.abs(a7)>bf){var be=a2,bh=a8,a5=bD;a2=a3+bf*(S&&a2>a3?1:-1);a8=bd+bi*ab.cos(a2);bD=bc+bg*ab.sin(a2);bm=K(a8,bD,bi,bg,ba,0,S,bh,a5,[a2,be,bd,bc]);}a7=a2-a3;var a1=ab.cos(a3),bC=ab.sin(a3),a0=ab.cos(a2),bB=ab.sin(a2),bp=ab.tan(a7/4),bs=4/3*bi*bp,bq=4/3*bg*bp,bz=[a9,bE],bx=[a9+bs*bC,bE-bq*a1],bw=[a8+bs*bB,bD-bq*a0],bu=[a8,bD];bx[0]=2*bz[0]-bx[0];bx[1]=2*bz[1]-bx[1];if(bb){return[bx,bw,bu][aS](bm);}else{bm=[bx,bw,bu][aS](bm)[az]()[z](",");var bk=[];for(var bv=0,bl=bm[m];bv<bl;bv++){bk[bv]=bv%2?bA(bm[bv-1],bm[bv],d).y:bA(bm[bv],bm[bv+1],d).x;}return bk;}},M=function(e,d,E,i,a2,a1,a0,S,a3){var R=1-a3;return{x:aM(R,3)*e+aM(R,2)*3*a3*E+R*3*a3*a3*a2+aM(a3,3)*a0,y:aM(R,3)*d+aM(R,2)*3*a3*i+R*3*a3*a3*a1+aM(a3,3)*S};},aC=aj(function(i,d,R,E,a9,a8,a5,a2){var a7=(a9-2*R+i)-(a5-2*a9+R),a4=2*(R-i)-2*(a9-R),a1=i-R,a0=(-a4+ab.sqrt(a4*a4-4*a7*a1))/2/a7,S=(-a4-ab.sqrt(a4*a4-4*a7*a1))/2/a7,a3=[d,a2],a6=[i,a5],e;ab.abs(a0)>1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}a7=(a8-2*E+d)-(a2-2*a8+E);a4=2*(E-d)-2*(a8-E);a1=d-E;a0=(-a4+ab.sqrt(a4*a4-4*a7*a1))/2/a7;S=(-a4-ab.sqrt(a4*a4-4*a7*a1))/2/a7;ab.abs(a0)>1000000000000&&(a0=0.5);ab.abs(S)>1000000000000&&(S=0.5);if(a0>0&&a0<1){e=M(i,d,R,E,a9,a8,a5,a2,a0);a6[f](e.x);a3[f](e.y);}if(S>0&&S<1){e=M(i,d,R,E,a9,a8,a5,a2,S);a6[f](e.x);a3[f](e.y);}return{min:{x:aI[aW](0,a6),y:aI[aW](0,a3)},max:{x:g[aW](0,a6),y:g[aW](0,a3)}};}),H=aj(function(a9,a4){var R=r(a9),a5=a4&&r(a4),a6={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},d={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},a0=function(ba,bb){var i,bc;if(!ba){return["C",bb.x,bb.y,bb.x,bb.y,bb.x,bb.y];}!(ba[0] in {T:1,Q:1})&&(bb.qx=bb.qy=null);switch(ba[0]){case"M":bb.X=ba[1];bb.Y=ba[2];break;case"A":ba=["C"][aS](K[aW](0,[bb.x,bb.y][aS](ba.slice(1))));break;case"S":i=bb.x+(bb.x-(bb.bx||bb.x));bc=bb.y+(bb.y-(bb.by||bb.y));ba=["C",i,bc][aS](ba.slice(1));break;case"T":bb.qx=bb.x+(bb.x-(bb.qx||bb.x));bb.qy=bb.y+(bb.y-(bb.qy||bb.y));ba=["C"][aS](aK(bb.x,bb.y,bb.qx,bb.qy,ba[1],ba[2]));break;case"Q":bb.qx=ba[1];bb.qy=ba[2];ba=["C"][aS](aK(bb.x,bb.y,ba[1],ba[2],ba[3],ba[4]));break;case"L":ba=["C"][aS](aX(bb.x,bb.y,ba[1],ba[2]));break;case"H":ba=["C"][aS](aX(bb.x,bb.y,ba[1],bb.y));break;case"V":ba=["C"][aS](aX(bb.x,bb.y,bb.x,ba[1]));break;case"Z":ba=["C"][aS](aX(bb.x,bb.y,bb.X,bb.Y));break;}return ba;},e=function(ba,bb){if(ba[bb][m]>7){ba[bb].shift();var bc=ba[bb];while(bc[m]){ba.splice(bb++,0,["C"][aS](bc.splice(0,6)));}ba.splice(bb,1);a7=g(R[m],a5&&a5[m]||0);}},E=function(be,bd,bb,ba,bc){if(be&&bd&&be[bc][0]=="M"&&bd[bc][0]!="M"){bd.splice(bc,0,["M",ba.x,ba.y]);bb.bx=0;bb.by=0;bb.x=be[bc][1];bb.y=be[bc][2];a7=g(R[m],a5&&a5[m]||0);}};for(var a2=0,a7=g(R[m],a5&&a5[m]||0);a2<a7;a2++){R[a2]=a0(R[a2],a6);e(R,a2);a5&&(a5[a2]=a0(a5[a2],d));a5&&e(a5,a2);E(R,a5,a6,d,a2);E(a5,R,d,a6,a2);var a1=R[a2],a8=a5&&a5[a2],S=a1[m],a3=a5&&a8[m];a6.x=a1[S-2];a6.y=a1[S-1];a6.bx=W(a1[S-4])||a6.x;a6.by=W(a1[S-3])||a6.y;d.bx=a5&&(W(a8[a3-4])||d.x);d.by=a5&&(W(a8[a3-3])||d.y);d.x=a5&&a8[a3-2];d.y=a5&&a8[a3-1];}return a5?[R,a5]:R;},null,av),p=aj(function(a4){var a3=[];for(var a0=0,a5=a4[m];a0<a5;a0++){var e={},a2=a4[a0].match(/^([^:]*):?([\d\.]*)/);e.color=an.getRGB(a2[1]);if(e.color.error){return null;}e.color=e.color.hex;a2[2]&&(e.offset=a2[2]+"%");a3[f](e);}for(var a0=1,a5=a3[m]-1;a0<a5;a0++){if(!a3[a0].offset){var E=W(a3[a0-1].offset||0),R=0;for(var S=a0+1;S<a5;S++){if(a3[S].offset){R=a3[S].offset;break;}}if(!R){R=100;S=a5;}R=W(R);var a1=(R-E)/(S-a0+1);for(;a0<S;a0++){E+=a1;a3[a0].offset=E+"%";}}}return a3;}),ao=function(){var i,e,R,E,d;if(an.is(arguments[0],"string")||an.is(arguments[0],"object")){if(an.is(arguments[0],"string")){i=L.getElementById(arguments[0]);}else{i=arguments[0];}if(i.tagName){if(arguments[1]==null){return{container:i,width:i.style.pixelWidth||i.offsetWidth,height:i.style.pixelHeight||i.offsetHeight};}else{return{container:i,width:arguments[1],height:arguments[2]};}}}else{if(an.is(arguments[0],al)&&arguments[m]>3){return{container:1,x:arguments[0],y:arguments[1],width:arguments[2],height:arguments[3]};}}},aG=function(d,i){var e=this;for(var E in i){if(i[Q](E)&&!(E in d)){switch(typeof i[E]){case"function":(function(R){d[E]=d===e?R:function(){return R[aW](e,arguments);};})(i[E]);break;case"object":d[E]=d[E]||{};aG.call(this,d[E],i[E]);break;default:d[E]=i[E];break;}}}},ak=function(d,e){d==e.top&&(e.top=d.prev);d==e.bottom&&(e.bottom=d.next);d.next&&(d.next.prev=d.prev);d.prev&&(d.prev.next=d.next);},Y=function(d,e){if(e.top===d){return;}ak(d,e);d.next=null;d.prev=e.top;e.top.next=d;e.top=d;},k=function(d,e){if(e.bottom===d){return;}ak(d,e);d.next=e.bottom;d.prev=null;e.bottom.prev=d;e.bottom=d;},A=function(e,d,i){ak(e,i);d==i.top&&(i.top=e);d.next&&(d.next.prev=e);e.next=d.next;e.prev=d;d.next=e;},aq=function(e,d,i){ak(e,i);d==i.bottom&&(i.bottom=e);d.prev&&(d.prev.next=e);e.prev=d.prev;d.prev=e;e.next=d;},s=function(d){return function(){throw new Error("Rapha\xebl: you are calling to method \u201c"+d+"\u201d of removed object");};},ar=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/;if(an.svg){aT[aY].svgns="http://www.w3.org/2000/svg";aT[aY].xlink="http://www.w3.org/1999/xlink";var O=function(d){return +d+(~~d===d)*0.5;},V=function(S){for(var e=0,E=S[m];e<E;e++){if(aZ.call(S[e][0])!="a"){for(var d=1,R=S[e][m];d<R;d++){S[e][d]=O(S[e][d]);}}else{S[e][6]=O(S[e][6]);S[e][7]=O(S[e][7]);}}return S;},aJ=function(i,d){if(d){for(var e in d){if(d[Q](e)){i[v](e,d[e]);}}}else{return L.createElementNS(aT[aY].svgns,i);}};an[aA]=function(){return"Your browser supports SVG.\nYou are running Rapha\xebl "+this.version;};var q=function(d,E){var e=aJ("path");E.canvas&&E.canvas[aL](e);var i=new ax(e,E);i.type="path";aa(i,{fill:"none",stroke:"#000",path:d});return i;};var b=function(E,a7,d){var a4="linear",a1=0.5,S=0.5,a9=E.style;a7=(a7+at)[aP](ar,function(bb,i,bc){a4="radial";if(i&&bc){a1=W(i);S=W(bc);var ba=((S>0.5)*2-1);aM(a1-0.5,2)+aM(S-0.5,2)>0.25&&(S=ab.sqrt(0.25-aM(a1-0.5,2))*ba+0.5)&&S!=0.5&&(S=S.toFixed(5)-0.00001*ba);}return at;});a7=a7[z](/\s*\-\s*/);if(a4=="linear"){var a0=a7.shift();a0=-W(a0);if(isNaN(a0)){return null;}var R=[0,0,ab.cos(a0*ab.PI/180),ab.sin(a0*ab.PI/180)],a6=1/(g(ab.abs(R[2]),ab.abs(R[3]))||1);R[2]*=a6;R[3]*=a6;if(R[2]<0){R[0]=-R[2];R[2]=0;}if(R[3]<0){R[1]=-R[3];R[3]=0;}}var a3=p(a7);if(!a3){return null;}var e=aJ(a4+"Gradient");e.id="r"+(an._id++)[aA](36);aJ(e,a4=="radial"?{fx:a1,fy:S}:{x1:R[0],y1:R[1],x2:R[2],y2:R[3]});d.defs[aL](e);for(var a2=0,a8=a3[m];a2<a8;a2++){var a5=aJ("stop");aJ(a5,{offset:a3[a2].offset?a3[a2].offset:!a2?"0%":"100%","stop-color":a3[a2].color||"#fff"});e[aL](a5);}aJ(E,{fill:"url(#"+e.id+")",opacity:1,"fill-opacity":1});a9.fill=at;a9.opacity=1;a9.fillOpacity=1;return 1;};var N=function(e){var d=e.getBBox();aJ(e.pattern,{patternTransform:an.format("translate({0},{1})",d.x,d.y)});};var aa=function(a6,bf){var a9={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},bb=a6.node,a7=a6.attrs,a3=a6.rotate(),S=function(bm,bl){bl=a9[aZ.call(bl)];if(bl){var bj=bm.attrs["stroke-width"]||"1",bh={round:bj,square:bj,butt:0}[bm.attrs["stroke-linecap"]||bf["stroke-linecap"]]||0,bk=[];var bi=bl[m];while(bi--){bk[bi]=bl[bi]*bj+((bi%2)?1:-1)*bh;}aJ(bb,{"stroke-dasharray":bk[az](",")});}};bf[Q]("rotation")&&(a3=bf.rotation);var a2=(a3+at)[z](a);if(!(a2.length-1)){a2=null;}else{a2[1]=+a2[1];a2[2]=+a2[2];}W(a3)&&a6.rotate(0,true);for(var ba in bf){if(bf[Q](ba)){if(!j[Q](ba)){continue;}var a8=bf[ba];a7[ba]=a8;switch(ba){case"rotation":a6.rotate(a8,true);break;case"href":case"title":case"target":var bd=bb.parentNode;if(aZ.call(bd.tagName)!="a"){var E=aJ("a");bd.insertBefore(E,bb);E[aL](bb);bd=E;}bd.setAttributeNS(a6.paper.xlink,ba,a8);break;case"cursor":bb.style.cursor=a8;break;case"clip-rect":var e=(a8+at)[z](a);if(e[m]==4){a6.clip&&a6.clip.parentNode.parentNode.removeChild(a6.clip.parentNode);var i=aJ("clipPath"),bc=aJ("rect");i.id="r"+(an._id++)[aA](36);aJ(bc,{x:e[0],y:e[1],width:e[2],height:e[3]});i[aL](bc);a6.paper.defs[aL](i);aJ(bb,{"clip-path":"url(#"+i.id+")"});a6.clip=bc;}if(!a8){var be=L.getElementById(bb.getAttribute("clip-path")[aP](/(^url\(#|\)$)/g,at));be&&be.parentNode.removeChild(be);aJ(bb,{"clip-path":at});delete a6.clip;}break;case"path":if(a8&&a6.type=="path"){a7.path=V(r(a8));aJ(bb,{d:a7.path});}break;case"width":bb[v](ba,a8);if(a7.fx){ba="x";a8=a7.x;}else{break;}case"x":if(a7.fx){a8=-a7.x-(a7.width||0);}case"rx":if(ba=="rx"&&a6.type=="rect"){break;}case"cx":a2&&(ba=="x"||ba=="cx")&&(a2[1]+=a8-a7[ba]);bb[v](ba,O(a8));a6.pattern&&N(a6);break;case"height":bb[v](ba,a8);if(a7.fy){ba="y";a8=a7.y;}else{break;}case"y":if(a7.fy){a8=-a7.y-(a7.height||0);}case"ry":if(ba=="ry"&&a6.type=="rect"){break;}case"cy":a2&&(ba=="y"||ba=="cy")&&(a2[2]+=a8-a7[ba]);bb[v](ba,O(a8));a6.pattern&&N(a6);break;case"r":if(a6.type=="rect"){aJ(bb,{rx:a8,ry:a8});}else{bb[v](ba,a8);}break;case"src":if(a6.type=="image"){bb.setAttributeNS(a6.paper.xlink,"href",a8);}break;case"stroke-width":bb.style.strokeWidth=a8;bb[v](ba,a8);if(a7["stroke-dasharray"]){S(a6,a7["stroke-dasharray"]);}break;case"stroke-dasharray":S(a6,a8);break;case"translation":var a0=(a8+at)[z](a);a0[0]=+a0[0]||0;a0[1]=+a0[1]||0;if(a2){a2[1]+=a0[0];a2[2]+=a0[1];}t.call(a6,a0[0],a0[1]);break;case"scale":var a0=(a8+at)[z](a);a6.scale(+a0[0]||1,+a0[1]||+a0[0]||1,+a0[2]||null,+a0[3]||null);break;case"fill":var R=(a8+at).match(c);if(R){var i=aJ("pattern"),a5=aJ("image");i.id="r"+(an._id++)[aA](36);aJ(i,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1});aJ(a5,{x:0,y:0});a5.setAttributeNS(a6.paper.xlink,"href",R[1]);i[aL](a5);var bg=L.createElement("img");bg.style.cssText="position:absolute;left:-9999em;top-9999em";bg.onload=function(){aJ(i,{width:this.offsetWidth,height:this.offsetHeight});aJ(a5,{width:this.offsetWidth,height:this.offsetHeight});L.body.removeChild(this);a6.paper.safari();};L.body[aL](bg);bg.src=R[1];a6.paper.defs[aL](i);bb.style.fill="url(#"+i.id+")";aJ(bb,{fill:"url(#"+i.id+")"});a6.pattern=i;a6.pattern&&N(a6);break;}if(!an.getRGB(a8).error){delete bf.gradient;delete a7.gradient;!an.is(a7.opacity,"undefined")&&an.is(bf.opacity,"undefined")&&aJ(bb,{opacity:a7.opacity});!an.is(a7["fill-opacity"],"undefined")&&an.is(bf["fill-opacity"],"undefined")&&aJ(bb,{"fill-opacity":a7["fill-opacity"]});}else{if((({circle:1,ellipse:1})[Q](a6.type)||(a8+at).charAt()!="r")&&b(bb,a8,a6.paper)){a7.gradient=a8;a7.fill="none";break;}}case"stroke":bb[v](ba,an.getRGB(a8).hex);break;case"gradient":(({circle:1,ellipse:1})[Q](a6.type)||(a8+at).charAt()!="r")&&b(bb,a8,a6.paper);break;case"opacity":case"fill-opacity":if(a7.gradient){var d=L.getElementById(bb.getAttribute("fill")[aP](/^url\(#|\)$/g,at));if(d){var a1=d.getElementsByTagName("stop");a1[a1[m]-1][v]("stop-opacity",a8);}break;}default:ba=="font-size"&&(a8=G(a8,10)+"px");var a4=ba[aP](/(\-.)/g,function(bh){return aN.call(bh.substring(1));});bb.style[a4]=a8;bb[v](ba,a8);break;}}}D(a6,bf);if(a2){a6.rotate(a2.join(am));}else{W(a3)&&a6.rotate(a3,true);}};var h=1.2;var D=function(d,R){if(d.type!="text"||!(R[Q]("text")||R[Q]("font")||R[Q]("font-size")||R[Q]("x")||R[Q]("y"))){return;}var a3=d.attrs,e=d.node,a5=e.firstChild?G(L.defaultView.getComputedStyle(e.firstChild,at).getPropertyValue("font-size"),10):10;if(R[Q]("text")){a3.text=R.text;while(e.firstChild){e.removeChild(e.firstChild);}var E=(R.text+at)[z]("\n");for(var S=0,a4=E[m];S<a4;S++){if(E[S]){var a1=aJ("tspan");S&&aJ(a1,{dy:a5*h,x:a3.x});a1[aL](L.createTextNode(E[S]));e[aL](a1);}}}else{var E=e.getElementsByTagName("tspan");for(var S=0,a4=E[m];S<a4;S++){S&&aJ(E[S],{dy:a5*h,x:a3.x});}}aJ(e,{y:a3.y});var a0=d.getBBox(),a2=a3.y-(a0.y+a0.height/2);a2&&isFinite(a2)&&aJ(e,{y:a3.y+a2});};var ax=function(e,d){var E=0,i=0;this[0]=e;this.id=an._oid++;this.node=e;e.raphael=this;this.paper=d;this.attrs=this.attrs||{};this.transformations=[];this._={tx:0,ty:0,rt:{deg:0,cx:0,cy:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null;};ax[aY].rotate=function(e,d,E){if(this.removed){return this;}if(e==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][az](am);}return this._.rt.deg;}var i=this.getBBox();e=(e+at)[z](a);if(e[m]-1){d=W(e[1]);E=W(e[2]);}e=W(e[0]);if(d!=null){this._.rt.deg=e;}else{this._.rt.deg+=e;}(E==null)&&(d=null);this._.rt.cx=d;this._.rt.cy=E;d=d==null?i.x+i.width/2:d;E=E==null?i.y+i.height/2:E;if(this._.rt.deg){this.transformations[0]=an.format("rotate({0} {1} {2})",this._.rt.deg,d,E);this.clip&&aJ(this.clip,{transform:an.format("rotate({0} {1} {2})",-this._.rt.deg,d,E)});}else{this.transformations[0]=at;this.clip&&aJ(this.clip,{transform:at});}aJ(this.node,{transform:this.transformations[az](am)});return this;};ax[aY].hide=function(){!this.removed&&(this.node.style.display="none");return this;};ax[aY].show=function(){!this.removed&&(this.node.style.display="");return this;};ax[aY].remove=function(){if(this.removed){return;}ak(this,this.paper);this.node.parentNode.removeChild(this.node);for(var d in this){delete this[d];}this.removed=true;};ax[aY].getBBox=function(){if(this.removed){return this;}if(this.type=="path"){return U(this.attrs.path);}if(this.node.style.display=="none"){this.show();var E=true;}var a1={};try{a1=this.node.getBBox();}catch(S){}finally{a1=a1||{};}if(this.type=="text"){a1={x:a1.x,y:Infinity,width:0,height:0};for(var d=0,R=this.node.getNumberOfChars();d<R;d++){var a0=this.node.getExtentOfChar(d);(a0.y<a1.y)&&(a1.y=a0.y);(a0.y+a0.height-a1.y>a1.height)&&(a1.height=a0.y+a0.height-a1.y);(a0.x+a0.width-a1.x>a1.width)&&(a1.width=a0.x+a0.width-a1.x);}}E&&this.hide();return a1;};ax[aY].attr=function(){if(this.removed){return this;}if(arguments[m]==0){var R={};for(var E in this.attrs){if(this.attrs[Q](E)){R[E]=this.attrs[E];}}this._.rt.deg&&(R.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(R.scale=this.scale());R.gradient&&R.fill=="none"&&(R.fill=R.gradient)&&delete R.gradient;return R;}if(arguments[m]==1&&an.is(arguments[0],"string")){if(arguments[0]=="translation"){return t.call(this);}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}if(arguments[0]=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient;}return this.attrs[arguments[0]];}if(arguments[m]==1&&an.is(arguments[0],"array")){var d={};for(var e in arguments[0]){if(arguments[0][Q](e)){d[arguments[0][e]]=this.attrs[arguments[0][e]];}}return d;}if(arguments[m]==2){var S={};S[arguments[0]]=arguments[1];aa(this,S);}else{if(arguments[m]==1&&an.is(arguments[0],"object")){aa(this,arguments[0]);}}return this;};ax[aY].toFront=function(){if(this.removed){return this;}this.node.parentNode[aL](this.node);var d=this.paper;d.top!=this&&Y(this,d);return this;};ax[aY].toBack=function(){if(this.removed){return this;}if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild);k(this,this.paper);var d=this.paper;}return this;};ax[aY].insertAfter=function(d){if(this.removed){return this;}var e=d.node;if(e.nextSibling){e.parentNode.insertBefore(this.node,e.nextSibling);}else{e.parentNode[aL](this.node);}A(this,d,this.paper);return this;};ax[aY].insertBefore=function(d){if(this.removed){return this;}var e=d.node;e.parentNode.insertBefore(this.node,e);aq(this,d,this.paper);return this;};var P=function(e,d,S,R){d=O(d);S=O(S);var E=aJ("circle");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:S,r:R,fill:"none",stroke:"#000"};i.type="circle";aJ(E,i.attrs);return i;};var aF=function(i,d,a1,e,S,a0){d=O(d);a1=O(a1);var R=aJ("rect");i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,r:a0||0,rx:a0||0,ry:a0||0,fill:"none",stroke:"#000"};E.type="rect";aJ(R,E.attrs);return E;};var ai=function(e,d,a0,S,R){d=O(d);a0=O(a0);var E=aJ("ellipse");e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={cx:d,cy:a0,rx:S,ry:R,fill:"none",stroke:"#000"};i.type="ellipse";aJ(E,i.attrs);return i;};var o=function(i,a0,d,a1,e,S){var R=aJ("image");aJ(R,{x:d,y:a1,width:e,height:S,preserveAspectRatio:"none"});R.setAttributeNS(i.xlink,"href",a0);i.canvas&&i.canvas[aL](R);var E=new ax(R,i);E.attrs={x:d,y:a1,width:e,height:S,src:a0};E.type="image";return E;};var X=function(e,d,S,R){var E=aJ("text");aJ(E,{x:d,y:S,"text-anchor":"middle"});e.canvas&&e.canvas[aL](E);var i=new ax(E,e);i.attrs={x:d,y:S,"text-anchor":"middle",text:R,font:j.font,stroke:"none",fill:"#000"};i.type="text";aa(i,i.attrs);return i;};var aV=function(e,d){this.width=e||this.width;this.height=d||this.height;this.canvas[v]("width",this.width);this.canvas[v]("height",this.height);return this;};var w=function(){var E=ao[aW](null,arguments),i=E&&E.container,e=E.x,a0=E.y,R=E.width,d=E.height;if(!i){throw new Error("SVG container not found.");}var S=aJ("svg");R=R||512;d=d||342;aJ(S,{xmlns:"http://www.w3.org/2000/svg",version:1.1,width:R,height:d});if(i==1){S.style.cssText="position:absolute;left:"+e+"px;top:"+a0+"px";L.body[aL](S);}else{if(i.firstChild){i.insertBefore(S,i.firstChild);}else{i[aL](S);}}i=new aT;i.width=R;i.height=d;i.canvas=S;aG.call(i,i,an.fn);i.clear();return i;};aT[aY].clear=function(){var d=this.canvas;while(d.firstChild){d.removeChild(d.firstChild);}this.bottom=this.top=null;(this.desc=aJ("desc"))[aL](L.createTextNode("Created with Rapha\xebl"));d[aL](this.desc);d[aL](this.defs=aJ("defs"));};aT[aY].remove=function(){this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if(an.vml){var aH=function(a8){var a5=/[ahqstv]/ig,a0=r;(a8+at).match(a5)&&(a0=H);a5=/[clmz]/g;if(a0==r&&!(a8+at).match(a5)){var e={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},R=/([clmz]),?([^clmz]*)/gi,S=/-?[^,\s-]+/g;var a4=(a8+at)[aP](R,function(a9,bb,i){var ba=[];i[aP](S,function(bc){ba[f](O(bc));});return e[bb]+ba;});return a4;}var a6=a0(a8),E,a4=[],d;for(var a2=0,a7=a6[m];a2<a7;a2++){E=a6[a2];d=aZ.call(a6[a2][0]);d=="z"&&(d="x");for(var a1=1,a3=E[m];a1<a3;a1++){d+=O(E[a1])+(a1!=a3-1?",":at);}a4[f](d);}return a4[az](am);};an[aA]=function(){return"Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl "+this.version;};var q=function(d,S){var E=ah("group");E.style.cssText="position:absolute;left:0;top:0;width:"+S.width+"px;height:"+S.height+"px";E.coordsize=S.coordsize;E.coordorigin=S.coordorigin;var i=ah("shape"),e=i.style;e.width=S.width+"px";e.height=S.height+"px";i.coordsize=this.coordsize;i.coordorigin=this.coordorigin;E[aL](i);var R=new ax(i,E,S);R.isAbsolute=true;R.type="path";R.path=[];R.Path=at;d&&aa(R,{fill:"none",stroke:"#000",path:d});S.canvas[aL](E);return R;};var aa=function(a3,a8){a3.attrs=a3.attrs||{};var a6=a3.node,a9=a3.attrs,a0=a6.style,E,bd=a3;for(var a1 in a8){if(a8[Q](a1)){a9[a1]=a8[a1];}}a8.href&&(a6.href=a8.href);a8.title&&(a6.title=a8.title);a8.target&&(a6.target=a8.target);a8.cursor&&(a0.cursor=a8.cursor);if(a8.path&&a3.type=="path"){a9.path=a8.path;a6.path=aH(a9.path);}if(a8.rotation!=null){a3.rotate(a8.rotation,true);}if(a8.translation){E=(a8.translation+at)[z](a);t.call(a3,E[0],E[1]);if(a3._.rt.cx!=null){a3._.rt.cx+=+E[0];a3._.rt.cy+=+E[1];a3.setBox(a3.attrs,E[0],E[1]);}}if(a8.scale){E=(a8.scale+at)[z](a);a3.scale(+E[0]||1,+E[1]||+E[0]||1,+E[2]||null,+E[3]||null);}if("clip-rect" in a8){var d=(a8["clip-rect"]+at)[z](a);if(d[m]==4){d[2]=+d[2]+(+d[0]);d[3]=+d[3]+(+d[1]);var a2=a6.clipRect||L.createElement("div"),bc=a2.style,S=a6.parentNode;bc.clip=an.format("rect({1}px {2}px {3}px {0}px)",d);if(!a6.clipRect){bc.position="absolute";bc.top=0;bc.left=0;bc.width=a3.paper.width+"px";bc.height=a3.paper.height+"px";S.parentNode.insertBefore(a2,S);a2[aL](S);a6.clipRect=a2;}}if(!a8["clip-rect"]){a6.clipRect&&(a6.clipRect.style.clip=at);}}if(a3.type=="image"&&a8.src){a6.src=a8.src;}if(a3.type=="image"&&a8.opacity){a6.filterOpacity=" progid:DXImageTransform.Microsoft.Alpha(opacity="+(a8.opacity*100)+")";a0.filter=(a6.filterMatrix||at)+(a6.filterOpacity||at);}a8.font&&(a0.font=a8.font);a8["font-family"]&&(a0.fontFamily='"'+a8["font-family"][z](",")[0][aP](/^['"]+|['"]+$/g,at)+'"');a8["font-size"]&&(a0.fontSize=a8["font-size"]);a8["font-weight"]&&(a0.fontWeight=a8["font-weight"]);a8["font-style"]&&(a0.fontStyle=a8["font-style"]);if(a8.opacity!=null||a8["stroke-width"]!=null||a8.fill!=null||a8.stroke!=null||a8["stroke-width"]!=null||a8["stroke-opacity"]!=null||a8["fill-opacity"]!=null||a8["stroke-dasharray"]!=null||a8["stroke-miterlimit"]!=null||a8["stroke-linejoin"]!=null||a8["stroke-linecap"]!=null){a6=a3.shape||a6;var a7=(a6.getElementsByTagName("fill")&&a6.getElementsByTagName("fill")[0]),ba=false;!a7&&(ba=a7=ah("fill"));if("fill-opacity" in a8||"opacity" in a8){var e=((+a9["fill-opacity"]+1||2)-1)*((+a9.opacity+1||2)-1);e<0&&(e=0);e>1&&(e=1);a7.opacity=e;}a8.fill&&(a7.on=true);if(a7.on==null||a8.fill=="none"){a7.on=false;}if(a7.on&&a8.fill){var i=a8.fill.match(c);if(i){a7.src=i[1];a7.type="tile";}else{a7.color=an.getRGB(a8.fill).hex;a7.src=at;a7.type="solid";if(an.getRGB(a8.fill).error&&(bd.type in {circle:1,ellipse:1}||(a8.fill+at).charAt()!="r")&&b(bd,a8.fill)){a9.fill="none";a9.gradient=a8.fill;}}}ba&&a6[aL](a7);var R=(a6.getElementsByTagName("stroke")&&a6.getElementsByTagName("stroke")[0]),bb=false;!R&&(bb=R=ah("stroke"));if((a8.stroke&&a8.stroke!="none")||a8["stroke-width"]||a8["stroke-opacity"]!=null||a8["stroke-dasharray"]||a8["stroke-miterlimit"]||a8["stroke-linejoin"]||a8["stroke-linecap"]){R.on=true;}(a8.stroke=="none"||R.on==null||a8.stroke==0||a8["stroke-width"]==0)&&(R.on=false);R.on&&a8.stroke&&(R.color=an.getRGB(a8.stroke).hex);var e=((+a9["stroke-opacity"]+1||2)-1)*((+a9.opacity+1||2)-1),a4=(W(a8["stroke-width"])||1)*0.75;e<0&&(e=0);e>1&&(e=1);a8["stroke-width"]==null&&(a4=a9["stroke-width"]);a8["stroke-width"]&&(R.weight=a4);a4&&a4<1&&(e*=a4)&&(R.weight=1);R.opacity=e;a8["stroke-linejoin"]&&(R.joinstyle=a8["stroke-linejoin"]||"miter");R.miterlimit=a8["stroke-miterlimit"]||8;a8["stroke-linecap"]&&(R.endcap=a8["stroke-linecap"]=="butt"?"flat":a8["stroke-linecap"]=="square"?"square":"round");if(a8["stroke-dasharray"]){var a5={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};R.dashstyle=a5[Q](a8["stroke-dasharray"])?a5[a8["stroke-dasharray"]]:at;}bb&&a6[aL](R);}if(bd.type=="text"){var a0=bd.paper.span.style;a9.font&&(a0.font=a9.font);a9["font-family"]&&(a0.fontFamily=a9["font-family"]);a9["font-size"]&&(a0.fontSize=a9["font-size"]);a9["font-weight"]&&(a0.fontWeight=a9["font-weight"]);a9["font-style"]&&(a0.fontStyle=a9["font-style"]);bd.node.string&&(bd.paper.span.innerHTML=(bd.node.string+at)[aP](/</g,"&#60;")[aP](/&/g,"&#38;")[aP](/\n/g,"<br>"));bd.W=a9.w=bd.paper.span.offsetWidth;bd.H=a9.h=bd.paper.span.offsetHeight;bd.X=a9.x;bd.Y=a9.y+O(bd.H/2);switch(a9["text-anchor"]){case"start":bd.node.style["v-text-align"]="left";bd.bbx=O(bd.W/2);break;case"end":bd.node.style["v-text-align"]="right";bd.bbx=-O(bd.W/2);break;default:bd.node.style["v-text-align"]="center";break;}}};var b=function(d,a1){d.attrs=d.attrs||{};var a2=d.attrs,a4=d.node.getElementsByTagName("fill"),S="linear",a0=".5 .5";d.attrs.gradient=a1;a1=(a1+at)[aP](ar,function(a6,a7,i){S="radial";if(a7&&i){a7=W(a7);i=W(i);aM(a7-0.5,2)+aM(i-0.5,2)>0.25&&(i=ab.sqrt(0.25-aM(a7-0.5,2))*((i>0.5)*2-1)+0.5);a0=a7+am+i;}return at;});a1=a1[z](/\s*\-\s*/);if(S=="linear"){var e=a1.shift();e=-W(e);if(isNaN(e)){return null;}}var R=p(a1);if(!R){return null;}d=d.shape||d.node;a4=a4[0]||ah("fill");if(R[m]){a4.on=true;a4.method="none";a4.type=(S=="radial")?"gradientradial":"gradient";a4.color=R[0].color;a4.color2=R[R[m]-1].color;var a5=[];for(var E=0,a3=R[m];E<a3;E++){R[E].offset&&a5[f](R[E].offset+am+R[E].color);}a4.colors&&(a4.colors.value=a5[m]?a5[az](","):"0% "+a4.color);if(S=="radial"){a4.focus="100%";a4.focussize=a0;a4.focusposition=a0;}else{a4.angle=(270-e)%360;}}return 1;};var ax=function(R,a0,d){var S=0,i=0,e=0,E=1;this[0]=R;this.id=an._oid++;this.node=R;R.raphael=this;this.X=0;this.Y=0;this.attrs={};this.Group=a0;this.paper=d;this._={tx:0,ty:0,rt:{deg:0},sx:1,sy:1};!d.bottom&&(d.bottom=this);this.prev=d.top;d.top&&(d.top.next=this);d.top=this;this.next=null;};ax[aY].rotate=function(e,d,i){if(this.removed){return this;}if(e==null){if(this._.rt.cx){return[this._.rt.deg,this._.rt.cx,this._.rt.cy][az](am);}return this._.rt.deg;}e=(e+at)[z](a);if(e[m]-1){d=W(e[1]);i=W(e[2]);}e=W(e[0]);if(d!=null){this._.rt.deg=e;}else{this._.rt.deg+=e;}i==null&&(d=null);this._.rt.cx=d;this._.rt.cy=i;this.setBox(this.attrs,d,i);this.Group.style.rotation=this._.rt.deg;return this;};ax[aY].setBox=function(bb,e,d){if(this.removed){return this;}var a5=this.Group.style,R=(this.shape&&this.shape.style)||this.node.style;bb=bb||{};for(var a9 in bb){if(bb[Q](a9)){this.attrs[a9]=bb[a9];}}e=e||this._.rt.cx;d=d||this._.rt.cy;var a7=this.attrs,a1,a0,a2,ba;switch(this.type){case"circle":a1=a7.cx-a7.r;a0=a7.cy-a7.r;a2=ba=a7.r*2;break;case"ellipse":a1=a7.cx-a7.rx;a0=a7.cy-a7.ry;a2=a7.rx*2;ba=a7.ry*2;break;case"rect":case"image":a1=+a7.x;a0=+a7.y;a2=a7.width||0;ba=a7.height||0;break;case"text":this.textpath.v=["m",O(a7.x),", ",O(a7.y-2),"l",O(a7.x)+1,", ",O(a7.y-2)][az](at);a1=a7.x-O(this.W/2);a0=a7.y-this.H/2;a2=this.W;ba=this.H;break;case"path":if(!this.attrs.path){a1=0;a0=0;a2=this.paper.width;ba=this.paper.height;}else{var a8=U(this.attrs.path);a1=a8.x;a0=a8.y;a2=a8.width;ba=a8.height;}break;default:a1=0;a0=0;a2=this.paper.width;ba=this.paper.height;break;}e=(e==null)?a1+a2/2:e;d=(d==null)?a0+ba/2:d;var E=e-this.paper.width/2,a4=d-this.paper.height/2;if(this.type=="path"||this.type=="text"){(a5.left!=E+"px")&&(a5.left=E+"px");(a5.top!=a4+"px")&&(a5.top=a4+"px");this.X=this.type=="text"?a1:-E;this.Y=this.type=="text"?a0:-a4;this.W=a2;this.H=ba;(R.left!=-E+"px")&&(R.left=-E+"px");(R.top!=-a4+"px")&&(R.top=-a4+"px");}else{(a5.left!=E+"px")&&(a5.left=E+"px");(a5.top!=a4+"px")&&(a5.top=a4+"px");this.X=a1;this.Y=a0;this.W=a2;this.H=ba;(a5.width!=this.paper.width+"px")&&(a5.width=this.paper.width+"px");(a5.height!=this.paper.height+"px")&&(a5.height=this.paper.height+"px");(R.left!=a1-E+"px")&&(R.left=a1-E+"px");(R.top!=a0-a4+"px")&&(R.top=a0-a4+"px");(R.width!=a2+"px")&&(R.width=a2+"px");(R.height!=ba+"px")&&(R.height=ba+"px");var S=(+bb.r||0)/aI(a2,ba);if(this.type=="rect"&&this.arcsize.toFixed(4)!=S.toFixed(4)&&(S||this.arcsize)){var a6=ah("roundrect"),bc={},a9=0,a3=this.events&&this.events[m];a6.arcsize=S;a6.raphael=this;this.Group[aL](a6);this.Group.removeChild(this.node);this[0]=this.node=a6;this.arcsize=S;for(var a9 in a7){bc[a9]=a7[a9];}delete bc.scale;this.attr(bc);if(this.events){for(;a9<a3;a9++){this.events[a9].unbind=ae(this.node,this.events[a9].name,this.events[a9].f,this);}}}}};ax[aY].hide=function(){!this.removed&&(this.Group.style.display="none");return this;};ax[aY].show=function(){!this.removed&&(this.Group.style.display="block");return this;};ax[aY].getBBox=function(){if(this.removed){return this;}if(this.type=="path"){return U(this.attrs.path);}return{x:this.X+(this.bbx||0),y:this.Y,width:this.W,height:this.H};};ax[aY].remove=function(){if(this.removed){return;}ak(this,this.paper);this.node.parentNode.removeChild(this.node);this.Group.parentNode.removeChild(this.Group);this.shape&&this.shape.parentNode.removeChild(this.shape);for(var d in this){delete this[d];}this.removed=true;};ax[aY].attr=function(){if(this.removed){return this;}if(arguments[m]==0){var E={};for(var e in this.attrs){if(this.attrs[Q](e)){E[e]=this.attrs[e];}}this._.rt.deg&&(E.rotation=this.rotate());(this._.sx!=1||this._.sy!=1)&&(E.scale=this.scale());E.gradient&&E.fill=="none"&&(E.fill=E.gradient)&&delete E.gradient;return E;}if(arguments[m]==1&&an.is(arguments[0],"string")){if(arguments[0]=="translation"){return t.call(this);}if(arguments[0]=="rotation"){return this.rotate();}if(arguments[0]=="scale"){return this.scale();}if(arguments[0]=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient){return this.attrs.gradient;}return this.attrs[arguments[0]];}if(this.attrs&&arguments[m]==1&&an.is(arguments[0],"array")){var d={};for(var e=0,R=arguments[0][m];e<R;e++){d[arguments[0][e]]=this.attrs[arguments[0][e]];}return d;}var S;if(arguments[m]==2){S={};S[arguments[0]]=arguments[1];}arguments[m]==1&&an.is(arguments[0],"object")&&(S=arguments[0]);if(S){if(S.text&&this.type=="text"){this.node.string=S.text;}aa(this,S);if(S.gradient&&(({circle:1,ellipse:1})[Q](this.type)||(S.gradient+at).charAt()!="r")){b(this,S.gradient);}(this.type!="path"||this._.rt.deg)&&this.setBox(this.attrs);}return this;};ax[aY].toFront=function(){!this.removed&&this.Group.parentNode[aL](this.Group);this.paper.top!=this&&Y(this,this.paper);return this;};ax[aY].toBack=function(){if(this.removed){return this;}if(this.Group.parentNode.firstChild!=this.Group){this.Group.parentNode.insertBefore(this.Group,this.Group.parentNode.firstChild);k(this,this.paper);}return this;};ax[aY].insertAfter=function(d){if(this.removed){return this;}if(d.Group.nextSibling){d.Group.parentNode.insertBefore(this.Group,d.Group.nextSibling);}else{d.Group.parentNode[aL](this.Group);}A(this,d,this.paper);return this;};ax[aY].insertBefore=function(d){if(this.removed){return this;}d.Group.parentNode.insertBefore(this.Group,d.Group);aq(this,d,this.paper);return this;};var P=function(e,d,a1,S){var R=ah("group"),a0=ah("oval"),i=a0.style;R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;R[aL](a0);var E=new ax(a0,R,e);E.type="circle";aa(E,{stroke:"#000",fill:"none"});E.attrs.cx=d;E.attrs.cy=a1;E.attrs.r=S;E.setBox({x:d-S,y:a1-S,width:S*2,height:S*2});e.canvas[aL](R);return E;},aF=function(e,a1,a0,a2,E,d){var R=ah("group"),i=ah("roundrect"),a3=(+d||0)/(aI(a2,E));R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;R[aL](i);i.arcsize=a3;var S=new ax(i,R,e);S.type="rect";aa(S,{stroke:"#000"});S.arcsize=a3;S.setBox({x:a1,y:a0,width:a2,height:E,r:d});e.canvas[aL](R);return S;},ai=function(d,a2,a1,i,e){var R=ah("group"),E=ah("oval"),a0=E.style;R.style.cssText="position:absolute;left:0;top:0;width:"+d.width+"px;height:"+d.height+"px";R.coordsize=d.coordsize;R.coordorigin=d.coordorigin;R[aL](E);var S=new ax(E,R,d);S.type="ellipse";aa(S,{stroke:"#000"});S.attrs.cx=a2;S.attrs.cy=a1;S.attrs.rx=i;S.attrs.ry=e;S.setBox({x:a2-i,y:a1-e,width:i*2,height:e*2});d.canvas[aL](R);return S;},o=function(e,d,a2,a1,a3,E){var R=ah("group"),i=ah("image"),a0=i.style;R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;i.src=d;R[aL](i);var S=new ax(i,R,e);S.type="image";S.attrs.src=d;S.attrs.x=a2;S.attrs.y=a1;S.attrs.w=a3;S.attrs.h=E;S.setBox({x:a2,y:a1,width:a3,height:E});e.canvas[aL](R);return S;},X=function(e,a2,a1,a3){var R=ah("group"),E=ah("shape"),a0=E.style,a4=ah("path"),d=a4.style,i=ah("textpath");R.style.cssText="position:absolute;left:0;top:0;width:"+e.width+"px;height:"+e.height+"px";R.coordsize=e.coordsize;R.coordorigin=e.coordorigin;a4.v=an.format("m{0},{1}l{2},{1}",O(a2),O(a1),O(a2)+1);a4.textpathok=true;a0.width=e.width;a0.height=e.height;i.string=a3+at;i.on=true;E[aL](i);E[aL](a4);R[aL](E);var S=new ax(i,R,e);S.shape=E;S.textpath=a4;S.type="text";S.attrs.text=a3;S.attrs.x=a2;S.attrs.y=a1;S.attrs.w=1;S.attrs.h=1;aa(S,{font:j.font,stroke:"none",fill:"#000"});S.setBox();e.canvas[aL](R);return S;},aV=function(i,d){var e=this.canvas.style;i==+i&&(i+="px");d==+d&&(d+="px");e.width=i;e.height=d;e.clip="rect(0 "+i+" "+d+" 0)";return this;},ah;L.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!L.namespaces.rvml&&L.namespaces.add("rvml","urn:schemas-microsoft-com:vml");ah=function(d){return L.createElement("<rvml:"+d+' class="rvml">');};}catch(af){ah=function(d){return L.createElement("<"+d+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');};}var w=function(){var i=ao[aW](null,arguments),d=i.container,a2=i.height,a3,e=i.width,a1=i.x,a0=i.y;if(!d){throw new Error("VML container not found.");}var R=new aT,S=R.canvas=L.createElement("div"),E=S.style;e=e||512;a2=a2||342;e==+e&&(e+="px");a2==+a2&&(a2+="px");R.width=1000;R.height=1000;R.coordsize="1000 1000";R.coordorigin="0 0";R.span=L.createElement("span");R.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";S[aL](R.span);E.cssText=an.format("width:{0};height:{1};position:absolute;clip:rect(0 {0} {1} 0);overflow:hidden",e,a2);if(d==1){L.body[aL](S);E.left=a1+"px";E.top=a0+"px";}else{d.style.width=e;d.style.height=a2;if(d.firstChild){d.insertBefore(S,d.firstChild);}else{d[aL](S);}}aG.call(R,R,an.fn);return R;};aT[aY].clear=function(){this.canvas.innerHTML=at;this.span=L.createElement("span");this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;";this.canvas[aL](this.span);this.bottom=this.top=null;};aT[aY].remove=function(){this.canvas.parentNode.removeChild(this.canvas);for(var d in this){this[d]=s(d);}};}if((/^Apple|^Google/).test(navigator.vendor)&&!(navigator.userAgent.indexOf("Version/4.0")+1)){aT[aY].safari=function(){var d=this.rect(-99,-99,this.width+99,this.height+99);setTimeout(function(){d.remove();});};}else{aT[aY].safari=function(){};}var ae=(function(){if(L.addEventListener){return function(R,i,e,d){var E=function(S){return e.call(d,S);};R.addEventListener(i,E,false);return function(){R.removeEventListener(i,E,false);return true;};};}else{if(L.attachEvent){return function(S,E,i,e){var R=function(a0){return i.call(e,a0||au.event);};S.attachEvent("on"+E,R);var d=function(){S.detachEvent("on"+E,R);return true;};return d;};}}})();for(var ac=F[m];ac--;){(function(d){ax[aY][d]=function(e){if(an.is(e,"function")){this.events=this.events||[];this.events.push({name:d,f:e,unbind:ae(this.shape||this.node,d,e,this)});}return this;};ax[aY]["un"+d]=function(E){var i=this.events,e=i[m];while(e--){if(i[e].name==d&&i[e].f==E){i[e].unbind();i.splice(e,1);!i.length&&delete this.events;return this;}}return this;};})(F[ac]);}ax[aY].hover=function(e,d){return this.mouseover(e).mouseout(d);};ax[aY].unhover=function(e,d){return this.unmouseover(e).unmouseout(d);};aT[aY].circle=function(d,i,e){return P(this,d||0,i||0,e||0);};aT[aY].rect=function(d,R,e,i,E){return aF(this,d||0,R||0,e||0,i||0,E||0);};aT[aY].ellipse=function(d,E,i,e){return ai(this,d||0,E||0,i||0,e||0);};aT[aY].path=function(d){d&&!an.is(d,"string")&&!an.is(d[0],"array")&&(d+=at);return q(an.format[aW](an,arguments),this);};aT[aY].image=function(E,d,R,e,i){return o(this,E||"about:blank",d||0,R||0,e||0,i||0);};aT[aY].text=function(d,i,e){return X(this,d||0,i||0,e||at);};aT[aY].set=function(d){arguments[m]>1&&(d=Array[aY].splice.call(arguments,0,arguments[m]));return new T(d);};aT[aY].setSize=aV;aT[aY].top=aT[aY].bottom=null;aT[aY].raphael=an;function u(){return this.x+am+this.y;}ax[aY].scale=function(a6,a5,E,e){if(a6==null&&a5==null){return{x:this._.sx,y:this._.sy,toString:u};}a5=a5||a6;!+a5&&(a5=a6);var ba,a8,a9,a7,bm=this.attrs;if(a6!=0){var a4=this.getBBox(),a1=a4.x+a4.width/2,R=a4.y+a4.height/2,bl=a6/this._.sx,bk=a5/this._.sy;E=(+E||E==0)?E:a1;e=(+e||e==0)?e:R;var a3=~~(a6/ab.abs(a6)),a0=~~(a5/ab.abs(a5)),be=this.node.style,bo=E+(a1-E)*bl,bn=e+(R-e)*bk;switch(this.type){case"rect":case"image":var a2=bm.width*a3*bl,bd=bm.height*a0*bk;this.attr({height:bd,r:bm.r*aI(a3*bl,a0*bk),width:a2,x:bo-a2/2,y:bn-bd/2});break;case"circle":case"ellipse":this.attr({rx:bm.rx*a3*bl,ry:bm.ry*a0*bk,r:bm.r*aI(a3*bl,a0*bk),cx:bo,cy:bn});break;case"path":var bg=ad(bm.path),bh=true;for(var bj=0,bc=bg[m];bj<bc;bj++){var bf=bg[bj],bi,S=aN.call(bf[0]);if(S=="M"&&bh){continue;}else{bh=false;}if(S=="A"){bf[bg[bj][m]-2]*=bl;bf[bg[bj][m]-1]*=bk;bf[1]*=a3*bl;bf[2]*=a0*bk;bf[5]=+(a3+a0?!!+bf[5]:!+bf[5]);}else{if(S=="H"){for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=bl;}}else{if(S=="V"){for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=bk;}}else{for(bi=1,jj=bf[m];bi<jj;bi++){bf[bi]*=(bi%2)?bl:bk;}}}}}var d=U(bg),ba=bo-d.x-d.width/2,a8=bn-d.y-d.height/2;bg[0][1]+=ba;bg[0][2]+=a8;this.attr({path:bg});break;}if(this.type in {text:1,image:1}&&(a3!=1||a0!=1)){if(this.transformations){this.transformations[2]="scale("[aS](a3,",",a0,")");this.node[v]("transform",this.transformations[az](am));ba=(a3==-1)?-bm.x-(a2||0):bm.x;a8=(a0==-1)?-bm.y-(bd||0):bm.y;this.attr({x:ba,y:a8});bm.fx=a3-1;bm.fy=a0-1;}else{this.node.filterMatrix=" progid:DXImageTransform.Microsoft.Matrix(M11="[aS](a3,", M12=0, M21=0, M22=",a0,", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')");be.filter=(this.node.filterMatrix||at)+(this.node.filterOpacity||at);}}else{if(this.transformations){this.transformations[2]=at;this.node[v]("transform",this.transformations[az](am));bm.fx=0;bm.fy=0;}else{this.node.filterMatrix=at;be.filter=(this.node.filterMatrix||at)+(this.node.filterOpacity||at);}}bm.scale=[a6,a5,E,e][az](am);this._.sx=a6;this._.sy=a5;}return this;};ax[aY].clone=function(){var d=this.attr();delete d.scale;delete d.translation;return this.paper[this.type]().attr(d);};var aB=function(d,e){return function(a9,S,a0){a9=H(a9);var a5,a4,E,a1,R="",a8={},a6,a3=0;for(var a2=0,a7=a9.length;a2<a7;a2++){E=a9[a2];if(E[0]=="M"){a5=+E[1];a4=+E[2];}else{a1=n(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6]);if(a3+a1>S){if(e&&!a8.start){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);R+=["C",a6.start.x,a6.start.y,a6.m.x,a6.m.y,a6.x,a6.y];if(a0){return R;}a8.start=R;R=["M",a6.x,a6.y+"C",a6.n.x,a6.n.y,a6.end.x,a6.end.y,E[5],E[6]][az]();a3+=a1;a5=+E[5];a4=+E[6];continue;}if(!d&&!e){a6=an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],(S-a3)/a1);return{x:a6.x,y:a6.y,alpha:a6.alpha};}}a3+=a1;a5=+E[5];a4=+E[6];}R+=E;}a8.end=R;a6=d?a3:e?a8:an.findDotsAtSegment(a5,a4,E[1],E[2],E[3],E[4],E[5],E[6],1);a6.alpha&&(a6={x:a6.x,y:a6.y,alpha:a6.alpha});return a6;};},n=aj(function(E,d,a0,S,a6,a5,a4,a3){var R={x:0,y:0},a2=0;for(var a1=0;a1<1.01;a1+=0.01){var e=M(E,d,a0,S,a6,a5,a4,a3,a1);a1&&(a2+=ab.sqrt(aM(R.x-e.x,2)+aM(R.y-e.y,2)));R=e;}return a2;});var ap=aB(1),C=aB(),J=aB(0,1);ax[aY].getTotalLength=function(){if(this.type!="path"){return;}return ap(this.attrs.path);};ax[aY].getPointAtLength=function(d){if(this.type!="path"){return;}return C(this.attrs.path,d);};ax[aY].getSubpath=function(i,e){if(this.type!="path"){return;}if(ab.abs(this.getTotalLength()-e)<0.000001){return J(this.attrs.path,i).end;}var d=J(this.attrs.path,e,1);return i?J(d,i).end:d;};an.easing_formulas={linear:function(d){return d;},"<":function(d){return aM(d,3);},">":function(d){return aM(d-1,3)+1;},"<>":function(d){d=d*2;if(d<1){return aM(d,3)/2;}d-=2;return(aM(d,3)+2)/2;},backIn:function(e){var d=1.70158;return e*e*((d+1)*e-d);},backOut:function(e){e=e-1;var d=1.70158;return e*e*((d+1)*e+d)+1;},elastic:function(i){if(i==0||i==1){return i;}var e=0.3,d=e/4;return aM(2,-10*i)*ab.sin((i-d)*(2*ab.PI)/e)+1;},bounce:function(E){var e=7.5625,i=2.75,d;if(E<(1/i)){d=e*E*E;}else{if(E<(2/i)){E-=(1.5/i);d=e*E*E+0.75;}else{if(E<(2.5/i)){E-=(2.25/i);d=e*E*E+0.9375;}else{E-=(2.625/i);d=e*E*E+0.984375;}}}return d;}};var I={length:0},aR=function(){var a2=+new Date;for(var be in I){if(be!="length"&&I[Q](be)){var bj=I[be];if(bj.stop){delete I[be];I[m]--;continue;}var a0=a2-bj.start,bb=bj.ms,ba=bj.easing,bf=bj.from,a7=bj.diff,E=bj.to,a6=bj.t,a9=bj.prev||0,a1=bj.el,R=bj.callback,a8={},d;if(a0<bb){var S=an.easing_formulas[ba]?an.easing_formulas[ba](a0/bb):a0/bb;for(var bc in bf){if(bf[Q](bc)){switch(Z[bc]){case"along":d=S*bb*a7[bc];E.back&&(d=E.len-d);var bd=C(E[bc],d);a1.translate(a7.sx-a7.x||0,a7.sy-a7.y||0);a7.x=bd.x;a7.y=bd.y;a1.translate(bd.x-a7.sx,bd.y-a7.sy);E.rot&&a1.rotate(a7.r+bd.alpha,bd.x,bd.y);break;case"number":d=+bf[bc]+S*bb*a7[bc];break;case"colour":d="rgb("+[B(O(bf[bc].r+S*bb*a7[bc].r)),B(O(bf[bc].g+S*bb*a7[bc].g)),B(O(bf[bc].b+S*bb*a7[bc].b))][az](",")+")";break;case"path":d=[];for(var bh=0,a5=bf[bc][m];bh<a5;bh++){d[bh]=[bf[bc][bh][0]];for(var bg=1,bi=bf[bc][bh][m];bg<bi;bg++){d[bh][bg]=+bf[bc][bh][bg]+S*bb*a7[bc][bh][bg];}d[bh]=d[bh][az](am);}d=d[az](am);break;case"csv":switch(bc){case"translation":var a4=a7[bc][0]*(a0-a9),a3=a7[bc][1]*(a0-a9);a6.x+=a4;a6.y+=a3;d=a4+am+a3;break;case"rotation":d=+bf[bc][0]+S*bb*a7[bc][0];bf[bc][1]&&(d+=","+bf[bc][1]+","+bf[bc][2]);break;case"scale":d=[+bf[bc][0]+S*bb*a7[bc][0],+bf[bc][1]+S*bb*a7[bc][1],(2 in E[bc]?E[bc][2]:at),(3 in E[bc]?E[bc][3]:at)][az](am);break;case"clip-rect":d=[];var bh=4;while(bh--){d[bh]=+bf[bc][bh]+S*bb*a7[bc][bh];}break;}break;}a8[bc]=d;}}a1.attr(a8);a1._run&&a1._run.call(a1);}else{if(E.along){var bd=C(E.along,E.len*!E.back);a1.translate(a7.sx-(a7.x||0)+bd.x-a7.sx,a7.sy-(a7.y||0)+bd.y-a7.sy);E.rot&&a1.rotate(a7.r+bd.alpha,bd.x,bd.y);}(a6.x||a6.y)&&a1.translate(-a6.x,-a6.y);E.scale&&(E.scale=E.scale+at);a1.attr(E);delete I[be];I[m]--;a1.in_animation=null;an.is(R,"function")&&R.call(a1);}bj.prev=a0;}}an.svg&&a1&&a1.paper.safari();I[m]&&setTimeout(aR);},B=function(d){return d>255?255:(d<0?0:d);},t=function(d,i){if(d==null){return{x:this._.tx,y:this._.ty,toString:u};}this._.tx+=+d;this._.ty+=+i;switch(this.type){case"circle":case"ellipse":this.attr({cx:+d+this.attrs.cx,cy:+i+this.attrs.cy});break;case"rect":case"image":case"text":this.attr({x:+d+this.attrs.x,y:+i+this.attrs.y});break;case"path":var e=ad(this.attrs.path);e[0][1]+=+d;e[0][2]+=+i;this.attr({path:e});break;}return this;};ax[aY].animateWith=function(e,i,d,R,E){I[e.id]&&(i.start=I[e.id].start);return this.animate(i,d,R,E);};ax[aY].animateAlong=ay();ax[aY].animateAlongBack=ay(1);function ay(d){return function(E,i,e,S){var R={back:d};an.is(e,"function")?(S=e):(R.rot=e);E&&E.constructor==ax&&(E=E.attrs.path);E&&(R.along=E);return this.animate(R,i,S);};}ax[aY].onAnimation=function(d){this._run=d||0;return this;};ax[aY].animate=function(be,a5,a4,E){if(an.is(a4,"function")||!a4){E=a4||null;}var a9={},e={},a2={};for(var a6 in be){if(be[Q](a6)){if(Z[Q](a6)){a9[a6]=this.attr(a6);(a9[a6]==null)&&(a9[a6]=j[a6]);e[a6]=be[a6];switch(Z[a6]){case"along":var bc=ap(be[a6]),a7=C(be[a6],bc*!!be.back),R=this.getBBox();a2[a6]=bc/a5;a2.tx=R.x;a2.ty=R.y;a2.sx=a7.x;a2.sy=a7.y;e.rot=be.rot;e.back=be.back;e.len=bc;be.rot&&(a2.r=W(this.rotate())||0);break;case"number":a2[a6]=(e[a6]-a9[a6])/a5;break;case"colour":a9[a6]=an.getRGB(a9[a6]);var a8=an.getRGB(e[a6]);a2[a6]={r:(a8.r-a9[a6].r)/a5,g:(a8.g-a9[a6].g)/a5,b:(a8.b-a9[a6].b)/a5};break;case"path":var S=H(a9[a6],e[a6]);a9[a6]=S[0];var a3=S[1];a2[a6]=[];for(var bb=0,a1=a9[a6][m];bb<a1;bb++){a2[a6][bb]=[0];for(var ba=1,bd=a9[a6][bb][m];ba<bd;ba++){a2[a6][bb][ba]=(a3[bb][ba]-a9[a6][bb][ba])/a5;}}break;case"csv":var d=(be[a6]+at)[z](a),a0=(a9[a6]+at)[z](a);switch(a6){case"translation":a9[a6]=[0,0];a2[a6]=[d[0]/a5,d[1]/a5];break;case"rotation":a9[a6]=(a0[1]==d[1]&&a0[2]==d[2])?a0:[0,d[1],d[2]];a2[a6]=[(d[0]-a9[a6][0])/a5,0,0];break;case"scale":be[a6]=d;a9[a6]=(a9[a6]+at)[z](a);a2[a6]=[(d[0]-a9[a6][0])/a5,(d[1]-a9[a6][1])/a5,0,0];break;case"clip-rect":a9[a6]=(a9[a6]+at)[z](a);a2[a6]=[];var bb=4;while(bb--){a2[a6][bb]=(d[bb]-a9[a6][bb])/a5;}break;}e[a6]=d;}}}}this.stop();this.in_animation=1;I[this.id]={start:be.start||+new Date,ms:a5,easing:a4,from:a9,diff:a2,to:e,el:this,callback:E,t:{x:0,y:0}};++I[m]==1&&aR();return this;};ax[aY].stop=function(){I[this.id]&&I[m]--;delete I[this.id];return this;};ax[aY].translate=function(d,e){return this.attr({translation:d+" "+e});};ax[aY][aA]=function(){return"Rapha\xebl\u2019s object";};an.ae=I;var T=function(d){this.items=[];this[m]=0;if(d){for(var e=0,E=d[m];e<E;e++){if(d[e]&&(d[e].constructor==ax||d[e].constructor==T)){this[this.items[m]]=this.items[this.items[m]]=d[e];this[m]++;}}}};T[aY][f]=function(){var R,d;for(var e=0,E=arguments[m];e<E;e++){R=arguments[e];if(R&&(R.constructor==ax||R.constructor==T)){d=this.items[m];this[d]=this.items[d]=R;this[m]++;}}return this;};T[aY].pop=function(){delete this[this[m]--];return this.items.pop();};for(var y in ax[aY]){if(ax[aY][Q](y)){T[aY][y]=(function(d){return function(){for(var e=0,E=this.items[m];e<E;e++){this.items[e][d][aW](this.items[e],arguments);}return this;};})(y);}}T[aY].attr=function(e,a0){if(e&&an.is(e,"array")&&an.is(e[0],"object")){for(var d=0,S=e[m];d<S;d++){this.items[d].attr(e[d]);}}else{for(var E=0,R=this.items[m];E<R;E++){this.items[E].attr[aW](this.items[E],arguments);}}return this;};T[aY].animate=function(S,e,a2,a1){(an.is(a2,"function")||!a2)&&(a1=a2||null);var d=this.items[m],E=d,a0=this,R;a1&&(R=function(){!--d&&a1.call(a0);});this.items[--E].animate(S,e,a2||R,R);while(E--){this.items[E].animateWith(this.items[d-1],S,e,a2||R,R);}return this;};T[aY].insertAfter=function(e){var d=this.items[m];while(d--){this.items[d].insertAfter(e);}return this;};T[aY].getBBox=function(){var d=[],a0=[],e=[],R=[];for(var E=this.items[m];E--;){var S=this.items[E].getBBox();d[f](S.x);a0[f](S.y);e[f](S.x+S.width);R[f](S.y+S.height);}d=aI[aW](0,d);a0=aI[aW](0,a0);return{x:d,y:a0,width:g[aW](0,e)-d,height:g[aW](0,R)-a0};};an.registerFont=function(e){if(!e.face){return e;}this.fonts=this.fonts||{};var E={w:e.w,face:{},glyphs:{}},i=e.face["font-family"];for(var a0 in e.face){if(e.face[Q](a0)){E.face[a0]=e.face[a0];}}if(this.fonts[i]){this.fonts[i][f](E);}else{this.fonts[i]=[E];}if(!e.svg){E.face["units-per-em"]=G(e.face["units-per-em"],10);for(var R in e.glyphs){if(e.glyphs[Q](R)){var S=e.glyphs[R];E.glyphs[R]={w:S.w,k:{},d:S.d&&"M"+S.d[aP](/[mlcxtrv]/g,function(a1){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a1]||"M";})+"z"};if(S.k){for(var d in S.k){if(S[Q](d)){E.glyphs[R].k[d]=S.k[d];}}}}}}return e;};aT[aY].getFont=function(a2,a3,e,R){R=R||"normal";e=e||"normal";a3=+a3||{normal:400,bold:700,lighter:300,bolder:800}[a3]||400;var S=an.fonts[a2];if(!S){var E=new RegExp("(^|\\s)"+a2[aP](/[^\w\d\s+!~.:_-]/g,at)+"(\\s|$)","i");for(var d in an.fonts){if(an.fonts[Q](d)){if(E.test(d)){S=an.fonts[d];break;}}}}var a0;if(S){for(var a1=0,a4=S[m];a1<a4;a1++){a0=S[a1];if(a0.face["font-weight"]==a3&&(a0.face["font-style"]==e||!a0.face["font-style"])&&a0.face["font-stretch"]==R){break;}}}return a0;};aT[aY].print=function(R,E,d,a1,a2,bb){bb=bb||"middle";var a7=this.set(),ba=(d+at)[z](at),a8=0,a4=at,bc;an.is(a1,"string")&&(a1=this.getFont(a1));if(a1){bc=(a2||16)/a1.face["units-per-em"];var e=a1.face.bbox.split(a),a0=+e[0],a3=+e[1]+(bb=="baseline"?e[3]-e[1]+(+a1.face.descent):(e[3]-e[1])/2);for(var a6=0,S=ba[m];a6<S;a6++){var a5=a6&&a1.glyphs[ba[a6-1]]||{},a9=a1.glyphs[ba[a6]];a8+=a6?(a5.w||a1.w)+(a5.k&&a5.k[ba[a6]]||0):0;a9&&a9.d&&a7[f](this.path(a9.d).attr({fill:"#000",stroke:"none",translation:[a8,0]}));}a7.scale(bc,bc,a0,a3).translate(R-a0,E-a3);}return a7;};an.format=function(i){var e=an.is(arguments[1],"array")?[0][aS](arguments[1]):arguments,d=/\{(\d+)\}/g;i&&an.is(i,"string")&&e[m]-1&&(i=i[aP](d,function(R,E){return e[++E]==null?at:e[E];}));return i||at;};an.ninja=function(){var d=Raphael;if(l.was){Raphael=l.is;}else{delete Raphael;}return d;};an.el=ax[aY];return an;})(); \ No newline at end of file
+// ┌─────────────────────────────────────────────────────────────────────┐ \\
+// │ Raphaël 2.0 - JavaScript Vector Library │ \\
+// ├─────────────────────────────────────────────────────────────────────┤ \\
+// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\
+// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\
+// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\
+// └─────────────────────────────────────────────────────────────────────┘ \\
+(function(a){var b="0.3.2",c="hasOwnProperty",d=/[\.\/]/,e="*",f=function(){},g=function(a,b){return a-b},h,i,j={n:{}},k=function(a,b){var c=j,d=i,e=Array.prototype.slice.call(arguments,2),f=k.listeners(a),l=0,m=!1,n,o=[],p={},q=[],r=[];h=a,i=0;for(var s=0,t=f.length;s<t;s++)"zIndex"in f[s]&&(o.push(f[s].zIndex),f[s].zIndex<0&&(p[f[s].zIndex]=f[s]));o.sort(g);while(o[l]<0){n=p[o[l++]],q.push(n.apply(b,e));if(i){i=d;return q}}for(s=0;s<t;s++){n=f[s];if("zIndex"in n)if(n.zIndex==o[l]){q.push(n.apply(b,e));if(i){i=d;return q}do{l++,n=p[o[l]],n&&q.push(n.apply(b,e));if(i){i=d;return q}}while(n)}else p[n.zIndex]=n;else{q.push(n.apply(b,e));if(i){i=d;return q}}}i=d;return q.length?q:null};k.listeners=function(a){var b=a.split(d),c=j,f,g,h,i,k,l,m,n,o=[c],p=[];for(i=0,k=b.length;i<k;i++){n=[];for(l=0,m=o.length;l<m;l++){c=o[l].n,g=[c[b[i]],c[e]],h=2;while(h--)f=g[h],f&&(n.push(f),p=p.concat(f.f||[]))}o=n}return p},k.on=function(a,b){var c=a.split(d),e=j;for(var g=0,h=c.length;g<h;g++)e=e.n,!e[c[g]]&&(e[c[g]]={n:{}}),e=e[c[g]];e.f=e.f||[];for(g=0,h=e.f.length;g<h;g++)if(e.f[g]==b)return f;e.f.push(b);return function(a){+a==+a&&(b.zIndex=+a)}},k.stop=function(){i=1},k.nt=function(a){if(a)return(new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)")).test(h);return h},k.unbind=function(a,b){var f=a.split(d),g,h,i,k=[j];for(var l=0,m=f.length;l<m;l++)for(var n=0;n<k.length;n+=i.length-2){i=[n,1],g=k[n].n;if(f[l]!=e)g[f[l]]&&i.push(g[f[l]]);else for(h in g)g[c](h)&&i.push(g[h]);k.splice.apply(k,i)}for(l=0,m=k.length;l<m;l++){g=k[l];while(g.n){if(b){if(g.f){for(n=0,jj=g.f.length;n<jj;n++)if(g.f[n]==b){g.f.splice(n,1);break}!g.f.length&&delete g.f}for(h in g.n)if(g.n[c](h)&&g.n[h].f){var o=g.n[h].f;for(n=0,jj=o.length;n<jj;n++)if(o[n]==b){o.splice(n,1);break}!o.length&&delete g.n[h].f}}else{delete g.f;for(h in g.n)g.n[c](h)&&g.n[h].f&&delete g.n[h].f}g=g.n}}},k.version=b,k.toString=function(){return"You are running Eve "+b},typeof module!="undefined"&&module.exports?module.exports=k:a.eve=k})(this),function(){function cr(b,d,e,f,h,i){e=Q(e);var j,k,l,m=[],o,p,q,t=b.ms,u={},v={},w={};if(f)for(y=0,z=cl.length;y<z;y++){var x=cl[y];if(x.el.id==d.id&&x.anim==b){x.percent!=e?(cl.splice(y,1),l=1):k=x,d.attr(x.totalOrigin);break}}else f=+v;for(var y=0,z=b.percents.length;y<z;y++){if(b.percents[y]==e||b.percents[y]>f*b.top){e=b.percents[y],p=b.percents[y-1]||0,t=t/b.top*(e-p),o=b.percents[y+1],j=b.anim[e];break}f&&d.attr(b.anim[b.percents[y]])}if(!!j){if(!k){for(attr in j)if(j[g](attr))if(U[g](attr)||d.paper.customAttributes[g](attr)){u[attr]=d.attr(attr),u[attr]==null&&(u[attr]=T[attr]),v[attr]=j[attr];switch(U[attr]){case C:w[attr]=(v[attr]-u[attr])/t;break;case"colour":u[attr]=a.getRGB(u[attr]);var A=a.getRGB(v[attr]);w[attr]={r:(A.r-u[attr].r)/t,g:(A.g-u[attr].g)/t,b:(A.b-u[attr].b)/t};break;case"path":var B=bG(u[attr],v[attr]),D=B[1];u[attr]=B[0],w[attr]=[];for(y=0,z=u[attr].length;y<z;y++){w[attr][y]=[0];for(var E=1,F=u[attr][y].length;E<F;E++)w[attr][y][E]=(D[y][E]-u[attr][y][E])/t}break;case"transform":var G=d._,H=bQ(G[attr],v[attr]);if(H){u[attr]=H.from,v[attr]=H.to,w[attr]=[],w[attr].real=!0;for(y=0,z=u[attr].length;y<z;y++){w[attr][y]=[u[attr][y][0]];for(E=1,F=u[attr][y].length;E<F;E++)w[attr][y][E]=(v[attr][y][E]-u[attr][y][E])/t}}else{var I=d.matrix||new bR,J={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};u[attr]=[I.a,I.b,I.c,I.d,I.e,I.f],bO(J,v[attr]),v[attr]=J._.transform,w[attr]=[(J.matrix.a-I.a)/t,(J.matrix.b-I.b)/t,(J.matrix.c-I.c)/t,(J.matrix.d-I.d)/t,(J.matrix.e-I.e)/t,(J.matrix.e-I.f)/t]}break;case"csv":var K=r(j[attr])[s](c),L=r(u[attr])[s](c);if(attr=="clip-rect"){u[attr]=L,w[attr]=[],y=L.length;while(y--)w[attr][y]=(K[y]-u[attr][y])/t}v[attr]=K;break;default:K=[][n](j[attr]),L=[][n](u[attr]),w[attr]=[],y=d.paper.customAttributes[attr].length;while(y--)w[attr][y]=((K[y]||0)-(L[y]||0))/t}}var M=j.easing,O=a.easing_formulas[M];if(!O){O=r(M).match(N);if(O&&O.length==5){var P=O;O=function(a){return cp(a,+P[1],+P[2],+P[3],+P[4],t)}}else O=be}q=j.start||b.start||+(new Date),x={anim:b,percent:e,timestamp:q,start:q+(b.del||0),status:0,initstatus:f||0,stop:!1,ms:t,easing:O,from:u,diff:w,to:v,el:d,callback:j.callback,prev:p,next:o,repeat:i||b.times,origin:d.attr(),totalOrigin:h},cl.push(x);if(f&&!k&&!l){x.stop=!0,x.start=new Date-t*f;if(cl.length==1)return cn()}l&&(x.start=new Date-x.ms*f),cl.length==1&&cm(cn)}else k.initstatus=f,k.start=new Date-k.ms*f;eve("anim.start."+d.id,d,b)}}function cq(a,b){var c=[],d={};this.ms=b,this.times=1;if(a){for(var e in a)a[g](e)&&(d[Q(e)]=a[e],c.push(Q(e)));c.sort(bc)}this.anim=d,this.top=c[c.length-1],this.percents=c}function cp(a,b,c,d,e,f){function o(a,b){var c,d,e,f,j,k;for(e=a,k=0;k<8;k++){f=m(e)-a;if(z(f)<b)return e;j=(3*i*e+2*h)*e+g;if(z(j)<1e-6)break;e=e-f/j}c=0,d=1,e=a;if(e<c)return c;if(e>d)return d;while(c<d){f=m(e);if(z(f-a)<b)return e;a>f?c=e:d=e,e=(d-c)/2+c}return e}function n(a,b){var c=o(a,b);return((l*c+k)*c+j)*c}function m(a){return((i*a+h)*a+g)*a}var g=3*b,h=3*(d-b)-g,i=1-g-h,j=3*c,k=3*(e-c)-j,l=1-j-k;return n(a,1/(200*f))}function cd(){return this.x+q+this.y+q+this.width+" × "+this.height}function cc(){return this.x+q+this.y}function bR(a,b,c,d,e,f){a!=null?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function bw(a){var b=[];for(var c=0,d=a.length;d-2>c;c+=2){var e=[{x:+a[c],y:+a[c+1]},{x:+a[c],y:+a[c+1]},{x:+a[c+2],y:+a[c+3]},{x:+a[c+4],y:+a[c+5]}];d-4==c?(e[0]={x:+a[c-2],y:+a[c-1]},e[3]=e[2]):c&&(e[0]={x:+a[c-2],y:+a[c-1]}),b.push(["C",(-e[0].x+6*e[1].x+e[2].x)/6,(-e[0].y+6*e[1].y+e[2].y)/6,(e[1].x+6*e[2].x-e[3].x)/6,(e[1].y+6*e[2].y-e[3].y)/6,e[2].x,e[2].y])}return b}function bv(){return this.hex}function bt(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),h=d.cache=d.cache||{},i=d.count=d.count||[];if(h[g](f)){bs(i,f);return c?c(h[f]):h[f]}i.length>=1e3&&delete h[i.shift()],i.push(f),h[f]=a[m](b,e);return c?c(h[f]):h[f]}return d}function bs(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function a(c){if(a.is(c,"function"))return b?c():eve.on("DOMload",c);if(a.is(c,E)){var e=c,f=a._engine.create[m](a,e.splice(0,3+a.is(e[0],C))),h=f.set(),i=0,j=e.length,k;for(;i<j;i++)k=e[i]||{},d[g](k.type)&&h.push(f[k.type]().attr(k));return h}var l=Array.prototype.slice.call(arguments,0);if(a.is(l[l.length-1],"function")){var n=l.pop();return b?n.call(a._engine.create[m](a,l)):eve.on("DOMload",function(){n.call(a._engine.create[m](a,l))})}return a._engine.create[m](a,arguments)}a.version="2.0.0",a.eve=eve;var b,c=/[, ]+/,d={circle:1,rect:1,path:1,ellipse:1,text:1,image:1},e=/\{(\d+)\}/g,f="prototype",g="hasOwnProperty",h={doc:document,win:window},i={was:Object.prototype[g].call(h.win,"Raphael"),is:h.win.Raphael},j=function(){this.ca=this.customAttributes={}},k,l="appendChild",m="apply",n="concat",o="createTouch"in h.doc,p="",q=" ",r=String,s="split",t="click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend touchcancel"[s](q),u={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},v=r.prototype.toLowerCase,w=Math,x=w.max,y=w.min,z=w.abs,A=w.pow,B=w.PI,C="number",D="string",E="array",F="toString",G="fill",H=Object.prototype.toString,I={},J="push",K=a._ISURL=/^url\(['"]?([^\)]+?)['"]?\)$/i,L=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i,M={NaN:1,Infinity:1,"-Infinity":1},N=/^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/,O=w.round,P="setAttribute",Q=parseFloat,R=parseInt,S=r.prototype.toUpperCase,T=a._availableAttrs={"arrow-end":"none","arrow-start":"none",blur:0,"clip-rect":"0 0 1e9 1e9",cursor:"default",cx:0,cy:0,fill:"#fff","fill-opacity":1,font:'10px "Arial"',"font-family":'"Arial"',"font-size":"10","font-style":"normal","font-weight":400,gradient:0,height:0,href:"http://raphaeljs.com/",opacity:1,path:"M0,0",r:0,rx:0,ry:0,src:"",stroke:"#000","stroke-dasharray":"","stroke-linecap":"butt","stroke-linejoin":"butt","stroke-miterlimit":0,"stroke-opacity":1,"stroke-width":1,target:"_blank","text-anchor":"middle",title:"Raphael",transform:"",width:0,x:0,y:0},U=a._availableAnimAttrs={blur:C,"clip-rect":"csv",cx:C,cy:C,fill:"colour","fill-opacity":C,"font-size":C,height:C,opacity:C,path:"path",r:C,rx:C,ry:C,stroke:"colour","stroke-opacity":C,"stroke-width":C,transform:"transform",width:C,x:C,y:C},V=/\s*,\s*/,W={hs:1,rg:1},X=/,?([achlmqrstvxz]),?/gi,Y=/([achlmrqstvz])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,Z=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?\s*,?\s*)+)/ig,$=/(-?\d*\.?\d*(?:e[\-+]?\d+)?)\s*,?\s*/ig,_=a._radial_gradient=/^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/,ba={},bb=function(a,b){return a.key-b.key},bc=function(a,b){return Q(a)-Q(b)},bd=function(){},be=function(a){return a},bf=a._rectPath=function(a,b,c,d,e){if(e)return[["M",a+e,b],["l",c-e*2,0],["a",e,e,0,0,1,e,e],["l",0,d-e*2],["a",e,e,0,0,1,-e,e],["l",e*2-c,0],["a",e,e,0,0,1,-e,-e],["l",0,e*2-d],["a",e,e,0,0,1,e,-e],["z"]];return[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]]},bg=function(a,b,c,d){d==null&&(d=c);return[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]]},bh=a._getPath={path:function(a){return a.attr("path")},circle:function(a){var b=a.attrs;return bg(b.cx,b.cy,b.r)},ellipse:function(a){var b=a.attrs;return bg(b.cx,b.cy,b.rx,b.ry)},rect:function(a){var b=a.attrs;return bf(b.x,b.y,b.width,b.height,b.r)},image:function(a){var b=a.attrs;return bf(b.x,b.y,b.width,b.height)},text:function(a){var b=a._getBBox();return bf(b.x,b.y,b.width,b.height)}},bi=a.mapPath=function(a,b){if(!b)return a;var c,d,e,f,g;a=bG(a);for(e=0,ii=a.length;e<ii;e++){g=a[e];for(f=1,jj=g.length;f<jj;f+=2)c=b.x(g[f],g[f+1]),d=b.y(g[f],g[f+1]),g[f]=c,g[f+1]=d}return a};a._g=h,a.type=h.win.SVGAngle||h.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML";if(a.type=="VML"){var bj=h.doc.createElement("div"),bk;bj.innerHTML='<v:shape adj="1"/>',bk=bj.firstChild,bk.style.behavior="url(#default#VML)";if(!bk||typeof bk.adj!="object")return a.type=p;bj=null}a.svg=!(a.vml=a.type=="VML"),a._Paper=j,a.fn=k=j.prototype=a.prototype,a._id=0,a._oid=0,a.is=function(a,b){b=v.call(b);if(b=="finite")return!M[g](+a);if(b=="array")return a instanceof Array;return b=="null"&&a===null||b==typeof a&&a!==null||b=="object"&&a===Object(a)||b=="array"&&Array.isArray&&Array.isArray(a)||H.call(a).slice(8,-1).toLowerCase()==b},a.angle=function(b,c,d,e,f,g){if(f==null){var h=b-d,i=c-e;if(!h&&!i)return 0;return(180+w.atan2(-i,-h)*180/B+360)%360}return a.angle(b,c,f,g)-a.angle(d,e,f,g)},a.rad=function(a){return a%360*B/180},a.deg=function(a){return a*180/B%360},a.snapTo=function(b,c,d){d=a.is(d,"finite")?d:10;if(a.is(b,E)){var e=b.length;while(e--)if(z(b[e]-c)<=d)return b[e]}else{b=+b;var f=c%b;if(f<d)return c-f;if(f>b-d)return c-f+b}return c};var bl=a.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=w.random()*16|0,c=a=="x"?b:b&3|8;return c.toString(16)});a.setWindow=function(b){eve("setWindow",a,h.win,b),h.win=b,h.doc=h.win.document,initWin&&initWin(h.win)};var bm=function(b){if(a.vml){var c=/^\s+|\s+$/g,d;try{var e=new ActiveXObject("htmlfile");e.write("<body>"),e.close(),d=e.body}catch(f){d=createPopup().document.body}var g=d.createTextRange();bm=bt(function(a){try{d.style.color=r(a).replace(c,p);var b=g.queryCommandValue("ForeColor");b=(b&255)<<16|b&65280|(b&16711680)>>>16;return"#"+("000000"+b.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=h.doc.createElement("i");i.title="Raphaël Colour Picker",i.style.display="none",h.doc.body.appendChild(i),bm=bt(function(a){i.style.color=a;return h.doc.defaultView.getComputedStyle(i,p).getPropertyValue("color")})}return bm(b)},bn=function(){return"hsb("+[this.h,this.s,this.b]+")"},bo=function(){return"hsl("+[this.h,this.s,this.l]+")"},bp=function(){return this.hex},bq=function(b,c,d){c==null&&a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b&&(d=b.b,c=b.g,b=b.r);if(c==null&&a.is(b,D)){var e=a.getRGB(b);b=e.r,c=e.g,d=e.b}if(b>1||c>1||d>1)b/=255,c/=255,d/=255;return[b,c,d]},br=function(b,c,d,e){b*=255,c*=255,d*=255;var f={r:b,g:c,b:d,hex:a.rgb(b,c,d),toString:bp};a.is(e,"finite")&&(f.opacity=e);return f};a.color=function(b){var c;a.is(b,"object")&&"h"in b&&"s"in b&&"b"in b?(c=a.hsb2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):a.is(b,"object")&&"h"in b&&"s"in b&&"l"in b?(c=a.hsl2rgb(b),b.r=c.r,b.g=c.g,b.b=c.b,b.hex=c.hex):(a.is(b,"string")&&(b=a.getRGB(b)),a.is(b,"object")&&"r"in b&&"g"in b&&"b"in b?(c=a.rgb2hsl(b),b.h=c.h,b.s=c.s,b.l=c.l,c=a.rgb2hsb(b),b.v=c.b):(b={hex:"none"},crl.r=b.g=b.b=b.h=b.s=b.v=b.l=-1)),b.toString=bp;return b},a.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;a=a%360/60,i=c*b,h=i*(1-z(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h);if(a>1||b>1||c>1)a/=360,b/=100,c/=100;a*=360;var e,f,g,h,i;a=a%360/60,i=2*b*(c<.5?c:1-c),h=i*(1-z(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a];return br(e,f,g,d)},a.rgb2hsb=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;f=x(a,b,c),g=f-y(a,b,c),d=g==0?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=g==0?0:g/f;return{h:d,s:e,b:f,toString:bn}},a.rgb2hsl=function(a,b,c){c=bq(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;g=x(a,b,c),h=y(a,b,c),i=g-h,d=i==0?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=i==0?0:f<.5?i/(2*f):i/(2-2*f);return{h:d,s:e,l:f,toString:bo}},a._path2string=function(){return this.join(",").replace(X,"$1")};var bu=a._preload=function(a,b){var c=h.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top-9999em",c.onload=function(){b.call(this),this.onload=null,h.doc.body.removeChild(this)},c.onerror=function(){h.doc.body.removeChild(this)},h.doc.body.appendChild(c),c.src=a};a.getRGB=bt(function(b){if(!b||!!((b=r(b)).indexOf("-")+1))return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv};if(b=="none")return{r:-1,g:-1,b:-1,hex:"none",toString:bv};!W[g](b.toLowerCase().substring(0,2))&&b.charAt()!="#"&&(b=bm(b));var c,d,e,f,h,i,j,k=b.match(L);if(k){k[2]&&(f=R(k[2].substring(5),16),e=R(k[2].substring(3,5),16),d=R(k[2].substring(1,3),16)),k[3]&&(f=R((i=k[3].charAt(3))+i,16),e=R((i=k[3].charAt(2))+i,16),d=R((i=k[3].charAt(1))+i,16)),k[4]&&(j=k[4][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),k[1].toLowerCase().slice(0,4)=="rgba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100));if(k[5]){j=k[5][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsba"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsb2rgb(d,e,f,h)}if(k[6]){j=k[6][s](V),d=Q(j[0]),j[0].slice(-1)=="%"&&(d*=2.55),e=Q(j[1]),j[1].slice(-1)=="%"&&(e*=2.55),f=Q(j[2]),j[2].slice(-1)=="%"&&(f*=2.55),(j[0].slice(-3)=="deg"||j[0].slice(-1)=="°")&&(d/=360),k[1].toLowerCase().slice(0,4)=="hsla"&&(h=Q(j[3])),j[3]&&j[3].slice(-1)=="%"&&(h/=100);return a.hsl2rgb(d,e,f,h)}k={r:d,g:e,b:f,toString:bv},k.hex="#"+(16777216|f|e<<8|d<<16).toString(16).slice(1),a.is(h,"finite")&&(k.opacity=h);return k}return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:bv}},a),a.hsb=bt(function(b,c,d){return a.hsb2rgb(b,c,d).hex}),a.hsl=bt(function(b,c,d){return a.hsl2rgb(b,c,d).hex}),a.rgb=bt(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),a.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b}));return c.hex},a.getColor.reset=function(){delete this.start},a.parsePathString=bt(function(b){if(!b)return null;var c={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Y,function(a,b,e){var f=[],g=b.toLowerCase();e.replace($,function(a,b){b&&f.push(+b)}),g=="m"&&f.length>2&&(d.push([b][n](f.splice(0,2))),g="l",b=b=="m"?"l":"L");if(g=="r")d.push([b][n](f));else while(f.length>=c[g]){d.push([b][n](f.splice(0,c[g])));if(!c[g])break}}),d.toString=a._path2string;return d}),a.parseTransformString=bt(function(b){if(!b)return null;var c={r:3,s:4,t:2,m:6},d=[];a.is(b,E)&&a.is(b[0],E)&&(d=by(b)),d.length||r(b).replace(Z,function(a,b,c){var e=[],f=v.call(b);c.replace($,function(a,b){b&&e.push(+b)}),d.push([b][n](e))}),d.toString=a._path2string;return d}),a.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=A(j,3),l=A(j,2),m=i*i,n=m*i,o=k*a+l*3*i*c+j*3*i*i*e+n*g,p=k*b+l*3*i*d+j*3*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,x=j*e+i*g,y=j*f+i*h,z=90-w.atan2(q-s,r-t)*180/B;(q>s||r<t)&&(z+=180);return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:x,y:y},alpha:z}};var bx=bt(function(a){if(!a)return{x:0,y:0,width:0,height:0};a=bG(a);var b=0,c=0,d=[],e=[],f;for(var g=0,h=a.length;g<h;g++){f=a[g];if(f[0]=="M")b=f[1],c=f[2],d.push(b),e.push(c);else{var i=bF(b,c,f[1],f[2],f[3],f[4],f[5],f[6]);d=d[n](i.min.x,i.max.x),e=e[n](i.min.y,i.max.y),b=f[5],c=f[6]}}var j=y[m](0,d),k=y[m](0,e);return{x:j,y:k,width:x[m](0,d)-j,height:x[m](0,e)-k}},null,function(a){return{x:a.x,y:a.y,width:a.width,height:a.height}}),by=function(b){var c=[];if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);for(var d=0,e=b.length;d<e;d++){c[d]=[];for(var f=0,g=b[d].length;f<g;f++)c[d][f]=b[d][f]}c.toString=a._path2string;return c},bz=a._pathToRelative=bt(function(b){if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=b[0][1],e=b[0][2],f=d,g=e,h++,c.push(["M",d,e]));for(var i=h,j=b.length;i<j;i++){var k=c[i]=[],l=b[i];if(l[0]!=v.call(l[0])){k[0]=v.call(l[0]);switch(k[0]){case"a":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]-d).toFixed(3),k[7]=+(l[7]-e).toFixed(3);break;case"v":k[1]=+(l[1]-e).toFixed(3);break;case"m":f=l[1],g=l[2];default:for(var m=1,n=l.length;m<n;m++)k[m]=+(l[m]-(m%2?d:e)).toFixed(3)}}else{k=c[i]=[],l[0]=="m"&&(f=l[1]+d,g=l[2]+e);for(var o=0,p=l.length;o<p;o++)c[i][o]=l[o]}var q=c[i].length;switch(c[i][0]){case"z":d=f,e=g;break;case"h":d+=+c[i][q-1];break;case"v":e+=+c[i][q-1];break;default:d+=+c[i][q-2],e+=+c[i][q-1]}}c.toString=a._path2string;return c},0,by),bA=a._pathToAbsolute=bt(function(b){if(!a.is(b,E)||!a.is(b&&b[0],E))b=a.parsePathString(b);if(!b||!b.length)return[["M",0,0]];var c=[],d=0,e=0,f=0,g=0,h=0;b[0][0]=="M"&&(d=+b[0][1],e=+b[0][2],f=d,g=e,h++,c[0]=["M",d,e]);for(var i,j,k=h,l=b.length;k<l;k++){c.push(i=[]),j=b[k];if(j[0]!=S.call(j[0])){i[0]=S.call(j[0]);switch(i[0]){case"A":i[1]=j[1],i[2]=j[2],i[3]=j[3],i[4]=j[4],i[5]=j[5],i[6]=+(j[6]+d),i[7]=+(j[7]+e);break;case"V":i[1]=+j[1]+e;break;case"H":i[1]=+j[1]+d;break;case"R":var m=[d,e][n](j.slice(1));for(var o=2,p=m.length;o<p;o++)m[o]=+m[o]+d,m[++o]=+m[o]+e;c.pop(),c=c[n](bw(m));break;case"M":f=+j[1]+d,g=+j[2]+e;default:for(o=1,p=j.length;o<p;o++)i[o]=+j[o]+(o%2?d:e)}}else if(j[0]=="R")m=[d,e][n](j.slice(1)),c.pop(),c=c[n](bw(m)),i=["R"][n](j.slice(-2));else for(var q=0,r=j.length;q<r;q++)i[q]=j[q];switch(i[0]){case"Z":d=f,e=g;break;case"H":d=i[1];break;case"V":e=i[1];break;case"M":f=i[i.length-2],g=i[i.length-1];default:d=i[i.length-2],e=i[i.length-1]}}c.toString=a._path2string;return c},null,by),bB=function(a,b,c,d){return[a,b,c,d,c,d]},bC=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},bD=function(a,b,c,d,e,f,g,h,i,j){var k=B*120/180,l=B/180*(+e||0),m=[],o,p=bt(function(a,b,c){var d=a*w.cos(c)-b*w.sin(c),e=a*w.sin(c)+b*w.cos(c);return{x:d,y:e}});if(!j){o=p(a,b,-l),a=o.x,b=o.y,o=p(h,i,-l),h=o.x,i=o.y;var q=w.cos(B/180*e),r=w.sin(B/180*e),t=(a-h)/2,u=(b-i)/2,v=t*t/(c*c)+u*u/(d*d);v>1&&(v=w.sqrt(v),c=v*c,d=v*d);var x=c*c,y=d*d,A=(f==g?-1:1)*w.sqrt(z((x*y-x*u*u-y*t*t)/(x*u*u+y*t*t))),C=A*c*u/d+(a+h)/2,D=A*-d*t/c+(b+i)/2,E=w.asin(((b-D)/d).toFixed(9)),F=w.asin(((i-D)/d).toFixed(9));E=a<C?B-E:E,F=h<C?B-F:F,E<0&&(E=B*2+E),F<0&&(F=B*2+F),g&&E>F&&(E=E-B*2),!g&&F>E&&(F=F-B*2)}else E=j[0],F=j[1],C=j[2],D=j[3];var G=F-E;if(z(G)>k){var H=F,I=h,J=i;F=E+k*(g&&F>E?1:-1),h=C+c*w.cos(F),i=D+d*w.sin(F),m=bD(h,i,c,d,e,0,g,I,J,[F,H,C,D])}G=F-E;var K=w.cos(E),L=w.sin(E),M=w.cos(F),N=w.sin(F),O=w.tan(G/4),P=4/3*c*O,Q=4/3*d*O,R=[a,b],S=[a+P*L,b-Q*K],T=[h+P*N,i-Q*M],U=[h,i];S[0]=2*R[0]-S[0],S[1]=2*R[1]-S[1];if(j)return[S,T,U][n](m);m=[S,T,U][n](m).join()[s](",");var V=[];for(var W=0,X=m.length;W<X;W++)V[W]=W%2?p(m[W-1],m[W],l).y:p(m[W],m[W+1],l).x;return V},bE=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:A(j,3)*a+A(j,2)*3*i*c+j*3*i*i*e+A(i,3)*g,y:A(j,3)*b+A(j,2)*3*i*d+j*3*i*i*f+A(i,3)*h}},bF=bt(function(a,b,c,d,e,f,g,h){var i=e-2*c+a-(g-2*e+c),j=2*(c-a)-2*(e-c),k=a-c,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,o=[b,h],p=[a,g],q;z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y)),i=f-2*d+b-(h-2*f+d),j=2*(d-b)-2*(f-d),k=b-d,l=(-j+w.sqrt(j*j-4*i*k))/2/i,n=(-j-w.sqrt(j*j-4*i*k))/2/i,z(l)>"1e12"&&(l=.5),z(n)>"1e12"&&(n=.5),l>0&&l<1&&(q=bE(a,b,c,d,e,f,g,h,l),p.push(q.x),o.push(q.y)),n>0&&n<1&&(q=bE(a,b,c,d,e,f,g,h,n),p.push(q.x),o.push(q.y));return{min:{x:y[m](0,p),y:y[m](0,o)},max:{x:x[m](0,p),y:x[m](0,o)}}}),bG=a._path2curve=bt(function(a,b){var c=bA(a),d=b&&bA(b),e={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g=function(a,b){var c,d;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null);switch(a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][n](bD[m](0,[b.x,b.y][n](a.slice(1))));break;case"S":c=b.x+(b.x-(b.bx||b.x)),d=b.y+(b.y-(b.by||b.y)),a=["C",c,d][n](a.slice(1));break;case"T":b.qx=b.x+(b.x-(b.qx||b.x)),b.qy=b.y+(b.y-(b.qy||b.y)),a=["C"][n](bC(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][n](bC(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][n](bB(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][n](bB(b.x,b.y,a[1],b.y));break;case"V":a=["C"][n](bB(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][n](bB(b.x,b.y,b.X,b.Y))}return a},h=function(a,b){if(a[b].length>7){a[b].shift();var e=a[b];while(e.length)a.splice(b++,0,["C"][n](e.splice(0,6)));a.splice(b,1),k=x(c.length,d&&d.length||0)}},i=function(a,b,e,f,g){a&&b&&a[g][0]=="M"&&b[g][0]!="M"&&(b.splice(g,0,["M",f.x,f.y]),e.bx=0,e.by=0,e.x=a[g][1],e.y=a[g][2],k=x(c.length,d&&d.length||0))};for(var j=0,k=x(c.length,d&&d.length||0);j<k;j++){c[j]=g(c[j],e),h(c,j),d&&(d[j]=g(d[j],f)),d&&h(d,j),i(c,d,e,f,j),i(d,c,f,e,j);var l=c[j],o=d&&d[j],p=l.length,q=d&&o.length;e.x=l[p-2],e.y=l[p-1],e.bx=Q(l[p-4])||e.x,e.by=Q(l[p-3])||e.y,f.bx=d&&(Q(o[q-4])||f.x),f.by=d&&(Q(o[q-3])||f.y),f.x=d&&o[q-2],f.y=d&&o[q-1]}return d?[c,d]:c},null,by),bH=a._parseDots=bt(function(b){var c=[];for(var d=0,e=b.length;d<e;d++){var f={},g=b[d].match(/^([^:]*):?([\d\.]*)/);f.color=a.getRGB(g[1]);if(f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),c.push(f)}for(d=1,e=c.length-1;d<e;d++)if(!c[d].offset){var h=Q(c[d-1].offset||0),i=0;for(var j=d+1;j<e;j++)if(c[j].offset){i=c[j].offset;break}i||(i=100,j=e),i=Q(i);var k=(i-h)/(j-d+1);for(;d<j;d++)h+=k,c[d].offset=h+"%"}return c}),bI=a._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)},bJ=a._tofront=function(a,b){b.top!==a&&(bI(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},bK=a._toback=function(a,b){b.bottom!==a&&(bI(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},bL=a._insertafter=function(a,b,c){bI(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},bM=a._insertbefore=function(a,b,c){bI(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},bN=function(a){return function(){throw new Error("Raphaël: you are calling to method “"+a+"” of removed object")}},bO=a._extractTransform=function(b,c){if(c==null)return b._.transform;c=r(c).replace(/\.{3}|\u2026/g,b._.transform||p);var d=a.parseTransformString(c),e=0,f=0,g=0,h=1,i=1,j=b._,k=new bR;j.transform=d||[];if(d)for(var l=0,m=d.length;l<m;l++){var n=d[l],o=n.length,q=r(n[0]).toLowerCase(),s=n[0]!=q,t=s?k.invert():0,u,v,w,x,y;q=="t"&&o==3?s?(u=t.x(0,0),v=t.y(0,0),w=t.x(n[1],n[2]),x=t.y(n[1],n[2]),k.translate(w-u,x-v)):k.translate(n[1],n[2]):q=="r"?o==2?(y=y||b.getBBox(1),k.rotate(n[1],y.x+y.width/2,y.y+y.height/2),e+=n[1]):o==4&&(s?(w=t.x(n[2],n[3]),x=t.y(n[2],n[3]),k.rotate(n[1],w,x)):k.rotate(n[1],n[2],n[3]),e+=n[1]):q=="s"?o==2||o==3?(y=y||b.getBBox(1),k.scale(n[1],n[o-1],y.x+y.width/2,y.y+y.height/2),h*=n[1],i*=n[o-1]):o==5&&(s?(w=t.x(n[3],n[4]),x=t.y(n[3],n[4]),k.scale(n[1],n[2],w,x)):k.scale(n[1],n[2],n[3],n[4]),h*=n[1],i*=n[2]):q=="m"&&o==7&&k.add(n[1],n[2],n[3],n[4],n[5],n[6]),j.dirtyT=1,b.matrix=k}b.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,h==1&&i==1&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1},bP=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return a.length==4?[b,0,a[2],a[3]]:[b,0];case"s":return a.length==5?[b,1,1,a[3],a[4]]:a.length==3?[b,1,1]:[b,1]}},bQ=a._equaliseTransform=function(b,c){c=r(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];var d=x(b.length,c.length),e=[],f=[],g=0,h,i,j,k;for(;g<d;g++){j=b[g]||bP(c[g]),k=c[g]||bP(j);if(j[0]!=k[0]||j[0].toLowerCase()=="r"&&(j[2]!=k[2]||j[3]!=k[3])||j[0].toLowerCase()=="s"&&(j[3]!=k[3]||j[4]!=k[4]))return;e[g]=[],f[g]=[];for(h=0,i=x(j.length,k.length);h<i;h++)h in j&&(e[g][h]=j[h]),h in k&&(f[g][h]=k[h])}return{from:e,to:f}};a._getContainer=function(b,c,d,e){var f;f=e==null&&!a.is(b,"object")?h.doc.getElementById(b):b;if(f!=null){if(f.tagName)return c==null?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:c,height:d};return{container:1,x:b,y:c,width:d,height:e}}},a.pathToRelative=bz,a._engine={},a.path2curve=bG,a.matrix=function(a,b,c,d,e,f){return new bR(a,b,c,d,e,f)},function(b){function d(a){var b=w.sqrt(c(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}function c(a){return a[0]*a[0]+a[1]*a[1]}b.add=function(a,b,c,d,e,f){var g=[[],[],[]],h=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],i=[[a,c,e],[b,d,f],[0,0,1]],j,k,l,m;a&&a instanceof bR&&(i=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]);for(j=0;j<3;j++)for(k=0;k<3;k++){m=0;for(l=0;l<3;l++)m+=h[j][l]*i[l][k];g[j][k]=m}this.a=g[0][0],this.b=g[1][0],this.c=g[0][1],this.d=g[1][1],this.e=g[0][2],this.f=g[1][2]},b.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new bR(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},b.clone=function(){return new bR(this.a,this.b,this.c,this.d,this.e,this.f)},b.translate=function(a,b){this.add(1,0,0,1,a,b)},b.scale=function(a,b,c,d){b==null&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},b.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var e=+w.cos(b).toFixed(9),f=+w.sin(b).toFixed(9);this.add(e,f,-f,e,c,d),this.add(1,0,0,1,-c,-d)},b.x=function(a,b){return a*this.a+b*this.c+this.e},b.y=function(a,b){return a*this.b+b*this.d+this.f},b.get=function(a){return+this[r.fromCharCode(97+a)].toFixed(4)},b.toString=function(){return a.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},b.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},b.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},b.split=function(){var b={};b.dx=this.e,b.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];b.scalex=w.sqrt(c(e[0])),d(e[0]),b.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*b.shear,e[1][1]-e[0][1]*b.shear],b.scaley=w.sqrt(c(e[1])),d(e[1]),b.shear/=b.scaley;var f=-e[0][1],g=e[1][1];g<0?(b.rotate=a.deg(w.acos(g)),f<0&&(b.rotate=360-b.rotate)):b.rotate=a.deg(w.asin(f)),b.isSimple=!+b.shear.toFixed(9)&&(b.scalex.toFixed(9)==b.scaley.toFixed(9)||!b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate;return b},b.toTransformString=function(a){var b=a||this[s]();return b.isSimple?"t"+[b.dx,b.dy]+"s"+[b.scalex,b.scaley,0,0]+"r"+[b.rotate,0,0]:"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(bR.prototype);var bS=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);navigator.vendor=="Apple Computer, Inc."&&(bS&&bS[1]<4||navigator.platform.slice(0,2)=="iP")||navigator.vendor=="Google Inc."&&bS&&bS[1]<8?k.safari=function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:k.safari=bd;var bT=function(){this.returnValue=!1},bU=function(){return this.originalEvent.preventDefault()},bV=function(){this.cancelBubble=!0},bW=function(){return this.originalEvent.stopPropagation()},bX=function(){if(h.doc.addEventListener)return function(a,b,c,d){var e=o&&u[b]?u[b]:b,f=function(e){var f=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,i=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,j=e.clientX+i,k=e.clientY+f;if(o&&u[g](b))for(var l=0,m=e.targetTouches&&e.targetTouches.length;l<m;l++)if(e.targetTouches[l].target==a){var n=e;e=e.targetTouches[l],e.originalEvent=n,e.preventDefault=bU,e.stopPropagation=bW;break}return c.call(d,e,j,k)};a.addEventListener(e,f,!1);return function(){a.removeEventListener(e,f,!1);return!0}};if(h.doc.attachEvent)return function(a,b,c,d){var e=function(a){a=a||h.win.event;var b=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;a.preventDefault=a.preventDefault||bT,a.stopPropagation=a.stopPropagation||bV;return c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){a.detachEvent("on"+b,e);return!0};return f}}(),bY=[],bZ=function(a){var b=a.clientX,c=a.clientY,d=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,e=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft,f,g=bY.length;while(g--){f=bY[g];if(o){var i=a.touches.length,j;while(i--){j=a.touches[i];if(j.identifier==f.el._drag.id){b=j.clientX,c=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}}else a.preventDefault();var k=f.el.node,l,m=k.nextSibling,n=k.parentNode,p=k.style.display;h.win.opera&&n.removeChild(k),k.style.display="none",l=f.el.paper.getElementByPoint(b,c),k.style.display=p,h.win.opera&&(m?n.insertBefore(k,m):n.appendChild(k)),l&&eve("drag.over."+f.el.id,f.el,l),b+=e,c+=d,eve("drag.move."+f.el.id,f.move_scope||f.el,b-f.el._drag.x,c-f.el._drag.y,b,c,a)}},b$=function(b){a.unmousemove(bZ).unmouseup(b$);var c=bY.length,d;while(c--)d=bY[c],d.el._drag={},eve("drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,b);bY=[]},b_=a.el={};for(var ca=t.length;ca--;)(function(b){a[b]=b_[b]=function(c,d){a.is(c,"function")&&(this.events=this.events||[],this.events.push({name:b,f:c,unbind:bX(this.shape||this.node||h.doc,b,c,d||this)}));return this},a["un"+b]=b_["un"+b]=function(a){var c=this.events,d=c.length;while(d--)if(c[d].name==b&&c[d].f==a){c[d].unbind(),c.splice(d,1),!c.length&&delete this.events;return this}return this}})(t[ca]);b_.data=function(b,c){var d=ba[this.id]=ba[this.id]||{};if(arguments.length==1){if(a.is(b,"object")){for(var e in b)b[g](e)&&this.data(e,b[e]);return this}eve("data.get."+this.id,this,d[b],b);return d[b]}d[b]=c,eve("data.set."+this.id,this,c,b);return this},b_.removeData=function(a){a==null?ba[this.id]={}:ba[this.id]&&delete ba[this.id][a];return this},b_.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},b_.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)},b_.drag=function(b,c,d,e,f,g){function i(i){(i.originalEvent||i).preventDefault();var j=h.doc.documentElement.scrollTop||h.doc.body.scrollTop,k=h.doc.documentElement.scrollLeft||h.doc.body.scrollLeft;this._drag.x=i.clientX+k,this._drag.y=i.clientY+j,this._drag.id=i.identifier,!bY.length&&a.mousemove(bZ).mouseup(b$),bY.push({el:this,move_scope:e,start_scope:f,end_scope:g}),c&&eve.on("drag.start."+this.id,c),b&&eve.on("drag.move."+this.id,b),d&&eve.on("drag.end."+this.id,d),eve("drag.start."+this.id,f||e||this,i.clientX+k,i.clientY+j,i)}this._drag={},this.mousedown(i);return this},b_.onDragOver=function(a){a?eve.on("drag.over."+this.id,a):eve.unbind("drag.over."+this.id)},b_.undrag=function(){var b=bY.length;while(b--)bY[b].el==this&&(a.unmousedown(bY[b].start),bY.splice(b++,1),eve.unbind("drag.*."+this.id));!bY.length&&a.unmousemove(bZ).unmouseup(b$)},k.circle=function(b,c,d){var e=a._engine.circle(this,b||0,c||0,d||0);this.__set__&&this.__set__.push(e);return e},k.rect=function(b,c,d,e,f){var g=a._engine.rect(this,b||0,c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.ellipse=function(b,c,d,e){var f=a._engine.ellipse(this,b||0,c||0,d||0,e||0);this.__set__&&this.__set__.push(f);return f},k.path=function(b){b&&!a.is(b,D)&&!a.is(b[0],E)&&(b+=p);var c=a._engine.path(a.format[m](a,arguments),this);this.__set__&&this.__set__.push(c);return c},k.image=function(b,c,d,e,f){var g=a._engine.image(this,b||"about:blank",c||0,d||0,e||0,f||0);this.__set__&&this.__set__.push(g);return g},k.text=function(b,c,d){var e=a._engine.text(this,b||0,c||0,r(d));this.__set__&&this.__set__.push(e);return e},k.set=function(b){!a.is(b,"array")&&(b=Array.prototype.splice.call(arguments,0,arguments.length));var c=new cs(b);this.__set__&&this.__set__.push(c);return c},k.setStart=function(a){this.__set__=a||this.set()},k.setFinish=function(a){var b=this.__set__;delete this.__set__;return b},k.setSize=function(b,c){return a._engine.setSize.call(this,b,c)},k.setViewBox=function(b,c,d,e,f){return a._engine.setViewBox.call(this,b,c,d,e,f)},k.top=k.bottom=null,k.raphael=a;var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,i=b.top+(h.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(h.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:i,x:j}};k.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=h.doc.elementFromPoint(a,b);if(h.win.opera&&e.tagName=="svg"){var f=cb(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var i=d.getIntersectionList(g,null);i.length&&(e=i[i.length-1])}if(!e)return null;while(e.parentNode&&e!=d.parentNode&&!e.raphael)e=e.parentNode;e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null;return e},k.getById=function(a){var b=this.bottom;while(b){if(b.id==a)return b;b=b.next}return null},k.forEach=function(a,b){var c=this.bottom;while(c){if(a.call(b,c)===!1)return this;c=c.next}return this},b_.getBBox=function(a){if(this.removed)return{};var b=this._;if(a){if(b.dirty||!b.bboxwt)this.realPath=bh[this.type](this),b.bboxwt=bx(this.realPath),b.bboxwt.toString=cd,b.dirty=0;return b.bboxwt}if(b.dirty||b.dirtyT||!b.bbox){if(b.dirty||!this.realPath)b.bboxwt=0,this.realPath=bh[this.type](this);b.bbox=bx(bi(this.realPath,this.matrix)),b.bbox.toString=cd,b.dirty=b.dirtyT=0}return b.bbox},b_.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());this.__set__&&this.__set__.push(a);return a},b_.glow=function(a){if(this.type=="text")return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||bh[this.type](this);f=this.matrix?bi(f,this.matrix):f;for(var g=1;g<c+1;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var ce={},cf=function(b,c,d,e,f,g,h,i,j){var k=0,l=100,m=[b,c,d,e,f,g,h,i].join(),n=ce[m],o,p;!n&&(ce[m]=n={data:[]}),n.timer&&clearTimeout(n.timer),n.timer=setTimeout(function(){delete ce[m]},2e3);if(j!=null&&!n.precision){var q=cf(b,c,d,e,f,g,h,i);n.precision=~~q*10,n.data=[]}l=n.precision||l;for(var r=0;r<l+1;r++){n.data[r*l]?p=n.data[r*l]:(p=a.findDotsAtSegment(b,c,d,e,f,g,h,i,r/l),n.data[r*l]=p),r&&(k+=A(A(o.x-p.x,2)+A(o.y-p.y,2),.5));if(j!=null&&k>=j)return p;o=p}if(j==null)return k},cg=function(b,c){return function(d,e,f){d=bG(d);var g,h,i,j,k="",l={},m,n=0;for(var o=0,p=d.length;o<p;o++){i=d[o];if(i[0]=="M")g=+i[1],h=+i[2];else{j=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6]);if(n+j>e){if(c&&!l.start){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),k+=["C"+m.start.x,m.start.y,m.m.x,m.m.y,m.x,m.y];if(f)return k;l.start=k,k=["M"+m.x,m.y+"C"+m.n.x,m.n.y,m.end.x,m.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!b&&!c){m=cf(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n);return{x:m.x,y:m.y,alpha:m.alpha}}}n+=j,g=+i[5],h=+i[6]}k+=i.shift()+i}l.end=k,m=b?n:c?l:a.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),m.alpha&&(m={x:m.x,y:m.y,alpha:m.alpha});return m}},ch=cg(1),ci=cg(),cj=cg(0,1);a.getTotalLength=ch,a.getPointAtLength=ci,a.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return cj(a,b).end;var d=cj(a,c,1);return b?cj(d,b).end:d},b_.getTotalLength=function(){if(this.type=="path"){if(this.node.getTotalLength)return this.node.getTotalLength();return ch(this.attrs.path)}},b_.getPointAtLength=function(a){if(this.type=="path")return ci(this.attrs.path,a)},b_.getSubpath=function(b,c){if(this.type=="path")return a.getSubpath(this.attrs.path,b,c)};var ck=a.easing_formulas={linear:function(a){return a},"<":function(a){return A(a,1.7)},">":function(a){return A(a,.48)},"<>":function(a){var b=.48-a/1.04,c=w.sqrt(.1734+b*b),d=c-b,e=A(z(d),1/3)*(d<0?-1:1),f=-c-b,g=A(z(f),1/3)*(f<0?-1:1),h=e+g+.5;return(1-h)*3*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a=a-1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){if(a==!!a)return a;return A(2,-10*a)*w.sin((a-.075)*2*B/.3)+1},bounce:function(a){var b=7.5625,c=2.75,d;a<1/c?d=b*a*a:a<2/c?(a-=1.5/c,d=b*a*a+.75):a<2.5/c?(a-=2.25/c,d=b*a*a+.9375):(a-=2.625/c,d=b*a*a+.984375);return d}};ck.easeIn=ck["ease-in"]=ck["<"],ck.easeOut=ck["ease-out"]=ck[">"],ck.easeInOut=ck["ease-in-out"]=ck["<>"],ck["back-in"]=ck.backIn,ck["back-out"]=ck.backOut;var cl=[],cm=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(a){setTimeout(a,16)},cn=function(){var b=+(new Date),c=0;for(;c<cl.length;c++){var d=cl[c];if(d.el.removed||d.paused)continue;var e=b-d.start,f=d.ms,h=d.easing,i=d.from,j=d.diff,k=d.to,l=d.t,m=d.el,o={},p,r={},s;d.initstatus?(e=(d.initstatus*d.anim.top-d.prev)/(d.percent-d.prev)*f,d.status=d.initstatus,delete d.initstatus,d.stop&&cl.splice(c--,1)):d.status=(d.prev+(d.percent-d.prev)*(e/f))/d.anim.top;if(e<0)continue;if(e<f){var t=h(e/f);for(var u in i)if(i[g](u)){switch(U[u]){case C:p=+i[u]+t*f*j[u];break;case"colour":p="rgb("+[co(O(i[u].r+t*f*j[u].r)),co(O(i[u].g+t*f*j[u].g)),co(O(i[u].b+t*f*j[u].b))].join(",")+")";break;case"path":p=[];for(var v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(var x=1,y=i[u][v].length;x<y;x++)p[v][x]=+i[u][v][x]+t*f*j[u][v][x];p[v]=p[v].join(q)}p=p.join(q);break;case"transform":if(j[u].real){p=[];for(v=0,w=i[u].length;v<w;v++){p[v]=[i[u][v][0]];for(x=1,y=i[u][v].length;x<y;x++)p[v][x]=i[u][v][x]+t*f*j[u][v][x]}}else{var z=function(a){return+i[u][a]+t*f*j[u][a]};p=[["m",z(0),z(1),z(2),z(3),z(4),z(5)]]}break;case"csv":if(u=="clip-rect"){p=[],v=4;while(v--)p[v]=+i[u][v]+t*f*j[u][v]}break;default:var A=[][n](i[u]);p=[],v=m.paper.customAttributes[u].length;while(v--)p[v]=+A[v]+t*f*j[u][v]}o[u]=p}m.attr(o),function(a,b,c){setTimeout(function(){eve("anim.frame."+a,b,c)})}(m.id,m,d.anim)}else{(function(b,c,d){setTimeout(function(){eve("anim.frame."+c.id,c,d),eve("anim.finish."+c.id,c,d),a.is(b,"function")&&b.call(c)})})(d.callback,m,d.anim),m.attr(k),cl.splice(c--,1);if(d.repeat>1&&!d.next){for(s in k)k[g](s)&&(r[s]=d.totalOrigin[s]);d.el.attr(r),cr(d.anim,d.el,d.anim.percents[0],null,d.totalOrigin,d.repeat-1)}d.next&&!d.stop&&cr(d.anim,d.el,d.next,null,d.totalOrigin,d.repeat)}}a.svg&&m&&m.paper&&m.paper.safari(),cl.length&&cm(cn)},co=function(a){return a>255?255:a<0?0:a};b_.animateWith=function(b,c,d,e,f,g){var h=d?a.animation(d,e,f,g):c;status=b.status(c);return this.animate(h).status(h,status*c.ms/h.ms)},b_.onAnimation=function(a){a?eve.on("anim.frame."+this.id,a):eve.unbind("anim.frame."+this.id);return this},cq.prototype.delay=function(a){var b=new cq(this.anim,this.ms);b.times=this.times,b.del=+a||0;return b},cq.prototype.repeat=function(a){var b=new cq(this.anim,this.ms);b.del=this.del,b.times=w.floor(x(a,0))||1;return b},a.animation=function(b,c,d,e){if(b instanceof cq)return b;if(a.is(d,"function")||!d)e=e||d||null,d=null;b=Object(b),c=+c||0;var f={},h,i;for(i in b)b[g](i)&&Q(i)!=i&&Q(i)+"%"!=i&&(h=!0,f[i]=b[i]);if(!h)return new cq(b,c);d&&(f.easing=d),e&&(f.callback=e);return new cq({100:f},c)},b_.animate=function(b,c,d,e){var f=this;if(f.removed){e&&e.call(f);return f}var g=b instanceof cq?b:a.animation(b,c,d,e);cr(g,f,g.percents[0],null,f.attr());return f},b_.setTime=function(a,b){a&&b!=null&&this.status(a,y(b,a.ms)/a.ms);return this},b_.status=function(a,b){var c=[],d=0,e,f;if(b!=null){cr(a,this,-1,y(b,1));return this}e=cl.length;for(;d<e;d++){f=cl[d];if(f.el.id==this.id&&(!a||f.anim==a)){if(a)return f.status;c.push({anim:f.anim,status:f.status})}}if(a)return 0;return c},b_.pause=function(a){for(var b=0;b<cl.length;b++)cl[b].el.id==this.id&&(!a||cl[b].anim==a)&&eve("anim.pause."+this.id,this,cl[b].anim)!==!1&&(cl[b].paused=!0);return this},b_.resume=function(a){for(var b=0;b<cl.length;b++)if(cl[b].el.id==this.id&&(!a||cl[b].anim==a)){var c=cl[b];eve("anim.resume."+this.id,this,c.anim)!==!1&&(delete c.paused,this.status(c.anim,c.status))}return this},b_.stop=function(a){for(var b=0;b<cl.length;b++)cl[b].el.id==this.id&&(!a||cl[b].anim==a)&&eve("anim.stop."+this.id,this,cl[b].anim)!==!1&&cl.splice(b--,1);return this},b_.toString=function(){return"Raphaël’s object"};var cs=function(a){this.items=[],this.length=0,this.type="set";if(a)for(var b=0,c=a.length;b<c;b++)a[b]&&(a[b].constructor==b_.constructor||a[b].constructor==cs)&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},ct=cs.prototype;ct.push=function(){var a,b;for(var c=0,d=arguments.length;c<d;c++)a=arguments[c],a&&(a.constructor==b_.constructor||a.constructor==cs)&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},ct.pop=function(){this.length&&delete this[this.length--];return this.items.pop()},ct.forEach=function(a,b){for(var c=0,d=this.items.length;c<d;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var cu in b_)b_[g](cu)&&(ct[cu]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][m](c,b)})}}(cu));ct.attr=function(b,c){if(b&&a.is(b,E)&&a.is(b[0],"object"))for(var d=0,e=b.length;d<e;d++)this.items[d].attr(b[d]);else for(var f=0,g=this.items.length;f<g;f++)this.items[f].attr(b,c);return this},ct.clear=function(){while(this.length)this.pop()},ct.splice=function(a,b,c){a=a<0?x(this.length+a,0):a,b=x(0,y(this.length-a,b));var d=[],e=[],f=[],g;for(g=2;g<arguments.length;g++)f.push(arguments[g]);for(g=0;g<b;g++)e.push(this[a+g]);for(;g<this.length-a;g++)d.push(this[a+g]);var h=f.length;for(g=0;g<h+d.length;g++)this.items[a+g]=this[a+g]=g<h?f[g]:d[g-h];g=this.items.length=this.length-=b-h;while(this[g])delete this[g++];return new cs(e)},ct.exclude=function(a){for(var b=0,c=this.length;b<c;b++)if(this[b]==a){this.splice(b,1);return!0}},ct.animate=function(b,c,d,e){(a.is(d,"function")||!d)&&(e=d||null);var f=this.items.length,g=f,h,i=this,j;if(!f)return this;e&&(j=function(){!--f&&e.call(i)}),d=a.is(d,D)?d:j;var k=a.animation(b,c,d,j);h=this.items[--g].animate(k);while(g--)this.items[g]&&!this.items[g].removed&&this.items[g].animateWith(h,k);return this},ct.insertAfter=function(a){var b=this.items.length;while(b--)this.items[b].insertAfter(a);return this},ct.getBBox=function(){var a=[],b=[],c=[],d=[];for(var e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}a=y[m](0,a),b=y[m](0,b);return{x:a,y:b,width:x[m](0,c)-a,height:x[m](0,d)-b}},ct.clone=function(a){a=new cs;for(var b=0,c=this.items.length;b<c;b++)a.push(this.items[b].clone());return a},ct.toString=function(){return"Raphaël‘s set"},a.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[g](d)&&(b.face[d]=a.face[d]);this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b];if(!a.svg){b.face["units-per-em"]=R(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[g](e)){var f=a.glyphs[e];b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"};if(f.k)for(var h in f.k)f[g](h)&&(b.glyphs[e].k[h]=f.k[h])}}return a},k.getFont=function(b,c,d,e){e=e||"normal",d=d||"normal",c=+c||{normal:400,bold:700,lighter:300,bolder:800}[c]||400;if(!!a.fonts){var f=a.fonts[b];if(!f){var h=new RegExp("(^|\\s)"+b.replace(/[^\w\d\s+!~.:_-]/g,p)+"(\\s|$)","i");for(var i in a.fonts)if(a.fonts[g](i)&&h.test(i)){f=a.fonts[i];break}}var j;if(f)for(var k=0,l=f.length;k<l;k++){j=f[k];if(j.face["font-weight"]==c&&(j.face["font-style"]==d||!j.face["font-style"])&&j.face["font-stretch"]==e)break}return j}},k.print=function(b,d,e,f,g,h,i){h=h||"middle",i=x(y(i||0,1),-1);var j=this.set(),k=r(e)[s](p),l=0,m=p,n;a.is(f,e)&&(f=this.getFont(f));if(f){n=(g||16)/f.face["units-per-em"];var o=f.face.bbox[s](c),q=+o[0],t=+o[1]+(h=="baseline"?o[3]-o[1]+ +f.face.descent:(o[3]-o[1])/2);for(var u=0,v=k.length;u<v;u++){var w=u&&f.glyphs[k[u-1]]||{},z=f.glyphs[k[u]];l+=u?(w.w||f.w)+(w.k&&w.k[k[u]]||0)+f.w*i:0,z&&z.d&&j.push(this.path(z.d).attr({fill:"#000",stroke:"none",transform:[["t",l*n,0]]}))}j.transform(["...s",n,n,q,t,"t",(b-q)/n,(d-t)/n])}return j},a.format=function(b,c){var d=a.is(c,E)?[0][n](c):arguments;b&&a.is(b,D)&&d.length-1&&(b=b.replace(e,function(a,b){return d[++b]==null?p:d[b]}));return b||p},a.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),typeof e=="function"&&f&&(e=e()))}),e=(e==null||e==d?a:e)+"";return e};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),a.ninja=function(){i.was?h.win.Raphael=i.is:delete Raphael;return a},a.st=ct,function(b,c,d){function e(){/in/.test(b.readyState)?setTimeout(e,9):a.eve("DOMload")}b.readyState==null&&b.addEventListener&&(b.addEventListener(c,d=function(){b.removeEventListener(c,d,!1),b.readyState="complete"},!1),b.readyState="loading"),e()}(document,"DOMContentLoaded"),i.was?h.win.Raphael=a:Raphael=a,eve.on("DOMload",function(){b=!0})}(),window.Raphael.svg&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=a.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};a.toString=function(){return"Your browser supports SVG.\nYou are running Raphaël "+this.version};var q=function(d,e){if(e){typeof d=="string"&&(d=q(d));for(var f in e)e[b](f)&&(f.substring(0,6)=="xlink:"?d.setAttributeNS(n,f.substring(6),c(e[f])):d.setAttribute(f,c(e[f])))}else d=a._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r={},s=/^url\(#(.*)\)$/,t=function(b,c){var d=b.getAttribute("fill");d=d&&d.match(s),d&&!--r[d[1]]&&(delete r[d[1]],c.defs.removeChild(a._g.doc.getElementById(d[1])))},u=function(b,e){var j="linear",k=b.id+e,m=.5,n=.5,o=b.node,p=b.paper,r=o.style,s=a._g.doc.getElementById(k);if(!s){e=c(e).replace(a._radial_gradient,function(a,b,c){j="radial";if(b&&c){m=d(b),n=d(c);var e=(n>.5)*2-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&n!=.5&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/);if(j=="linear"){var t=e.shift();t=-d(t);if(isNaN(t))return null;var u=[0,0,f.cos(a.rad(t)),f.sin(a.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=a._parseDots(e);if(!w)return null;b.gradient&&(p.defs.removeChild(b.gradient),delete b.gradient),k=k.replace(/[\(\)\s,\xb0#]/g,"-"),s=q(j+"Gradient",{id:k}),b.gradient=s,q(s,j=="radial"?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:b.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;x<y;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1;return 1},v=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},w=function(d,e,f){if(d.type=="path"){var g=c(e).toLowerCase().split("-"),h=d.paper,i=f?"end":"start",j=d.node,k=d.attrs,l=k["stroke-width"],n=g.length,r="classic",s,t,u,v,w,x=3,y=3,z=5;while(n--)switch(g[n]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":r=g[n];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}r=="open"?(x+=2,y+=2,z+=2,u=1,v=f?4:1,w={fill:"none",stroke:k.stroke}):(v=u=x/2,w={fill:k.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={};if(r!="none"){var A="raphael-marker-"+r,B="raphael-marker-"+i+r+x+y;a._g.doc.getElementById(A)?p[A]++:(h.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[r],id:A})),p[A]=1);var C=a._g.doc.getElementById(B),D;C?(p[B]++,D=C.getElementsByTagName("use")[0]):(C=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:v,refY:y/2}),D=q(q("use"),{"xlink:href":"#"+A,transform:(f?" rotate(180 "+x/2+" "+y/2+") ":m)+"scale("+x/z+","+y/z+")","stroke-width":1/((x/z+y/z)/2)}),C.appendChild(D),h.defs.appendChild(C),p[B]=1),q(D,w);var E=u*(r!="diamond"&&r!="oval");f?(s=d._.arrows.startdx*l||0,t=a.getTotalLength(k.path)-E*l):(s=E*l,t=a.getTotalLength(k.path)-(d._.arrows.enddx*l||0)),w={},w["marker-"+i]="url(#"+B+")";if(t||s)w.d=Raphael.getSubpath(k.path,s,t);q(j,w),d._.arrows[i+"Path"]=A,d._.arrows[i+"Marker"]=B,d._.arrows[i+"dx"]=E,d._.arrows[i+"Type"]=r,d._.arrows[i+"String"]=e}else f?(s=d._.arrows.startdx*l||0,t=a.getTotalLength(k.path)-s):(s=0,t=a.getTotalLength(k.path)-(d._.arrows.enddx*l||0)),d._.arrows[i+"Path"]&&q(j,{d:Raphael.getSubpath(k.path,s,t)}),delete d._.arrows[i+"Path"],delete d._.arrows[i+"Marker"],delete d._.arrows[i+"dx"],delete d._.arrows[i+"Type"],delete d._.arrows[i+"String"];for(w in p)if(p[b](w)&&!p[w]){var F=a._g.doc.getElementById(w);F&&F.parentNode.removeChild(F)}}},x={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},y=function(a,b,d){b=x[c(b).toLowerCase()];if(b){var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=b.length;while(h--)g[h]=b[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},z=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[b](o)){if(!a._availableAttrs[b](o))continue;var p=f[o];k[o]=p;switch(o){case"blur":d.blur(p);break;case"href":case"title":case"target":var r=i.parentNode;if(r.tagName.toLowerCase()!="a"){var s=q("a");r.insertBefore(s,i),s.appendChild(i),r=s}o=="target"&&p=="blank"?r.setAttributeNS(n,"show","new"):r.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":w(d,p);break;case"arrow-end":w(d,p,1);break;case"clip-rect":var t=c(p).split(j);if(t.length==4){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var x=q("clipPath"),z=q("rect");x.id=a.createUUID(),q(z,{x:t[0],y:t[1],width:t[2],height:t[3]}),x.appendChild(z),d.paper.defs.appendChild(x),q(i,{"clip-path":"url(#"+x.id+")"}),d.clip=z}if(!p){var A=a._g.doc.getElementById(i.getAttribute("clip-path").replace(/(^url\(#|\)$)/g,l));A&&A.parentNode.removeChild(A),q(i,{"clip-path":l}),delete d.clip}break;case"path":d.type=="path"&&(q(i,{d:p?k.path=a._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&w(d,d._.arrows.startString),"endString"in d._.arrows&&w(d,d._.arrows.endString,1)));break;case"width":i.setAttribute(o,p),d._.dirty=1;if(k.fx)o="x",p=k.x;else break;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if(o=="rx"&&d.type=="rect")break;case"cx":i.setAttribute(o,p),d.pattern&&v(d),d._.dirty=1;break;case"height":i.setAttribute(o,p),d._.dirty=1;if(k.fy)o="y",p=k.y;else break;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if(o=="ry"&&d.type=="rect")break;case"cy":i.setAttribute(o,p),d.pattern&&v(d),d._.dirty=1;break;case"r":d.type=="rect"?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":d.type=="image"&&i.setAttributeNS(n,"href",p);break;case"stroke-width":if(d._.sx!=1||d._.sy!=1)p/=g(h(d._.sx),h(d._.sy))||1;d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&y(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&w(d,d._.arrows.startString),"endString"in d._.arrows&&w(d,d._.arrows.endString,1));break;case"stroke-dasharray":y(d,p,f);break;case"fill":var C=c(p).match(a._ISURL);if(C){x=q("pattern");var D=q("image");x.id=a.createUUID(),q(x,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(D,{x:0,y:0,"xlink:href":C[1]}),x.appendChild(D),function(b){a._preload(C[1],function(){var a=this.offsetWidth,c=this.offsetHeight;q(b,{width:a,height:c}),q(D,{width:a,height:c}),d.paper.safari()})}(x),d.paper.defs.appendChild(x),i.style.fill="url(#"+x.id+")",q(i,{fill:"url(#"+x.id+")"}),d.pattern=x,d.pattern&&v(d);break}var E=a.getRGB(p);if(!E.error)delete f.gradient,delete k.gradient,!a.is(k.opacity,"undefined")&&a.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!a.is(k["fill-opacity"],"undefined")&&a.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});else if((d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&u(d,p)){if("opacity"in k||"fill-opacity"in k){var F=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(F){var G=F.getElementsByTagName("stop");q(G[G.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}E[b]("opacity")&&q(i,{"fill-opacity":E.opacity>1?E.opacity/100:E.opacity});case"stroke":E=a.getRGB(p),i.setAttribute(o,E.hex),o=="stroke"&&E[b]("opacity")&&q(i,{"stroke-opacity":E.opacity>1?E.opacity/100:E.opacity}),o=="stroke"&&d._.arrows&&("startString"in d._.arrows&&w(d,d._.arrows.startString),"endString"in d._.arrows&&w(d,d._.arrows.endString,1));break;case"gradient":(d.type=="circle"||d.type=="ellipse"||c(p).charAt()!="r")&&u(d,p);break;case"opacity":k.gradient&&!k[b]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){F=a._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),F&&(G=F.getElementsByTagName("stop"),q(G[G.length-1],{"stop-opacity":p}));break};default:o=="font-size"&&(p=e(p,10)+"px");var H=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[H]=p,d._.dirty=1,i.setAttribute(o,p)}}B(d,f),i.style.visibility=m},A=1.2,B=function(d,f){if(d.type=="text"&&!!(f[b]("text")||f[b]("font")||f[b]("font-size")||f[b]("x")||f[b]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(a._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10;if(f[b]("text")){g.text=f.text;while(h.firstChild)h.removeChild(h.firstChild);var j=c(f.text).split("\n"),k=[],m;for(var n=0,o=j.length;n<o;n++)m=q("tspan"),n&&q(m,{dy:i*A,x:g.x}),m.appendChild(a._g.doc.createTextNode(j[n])),h.appendChild(m),k[n]=m}else{k=h.getElementsByTagName("tspan");for(n=0,o=k.length;n<o;n++)n?q(k[n],{dy:i*A,x:g.x}):q(k[0],{dy:0})}q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&a.is(r,"finite")&&q(k[0],{dy:r})}},C=function(b,c){var d=0,e=0;this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.matrix=a.matrix(),this.realPath=null,this.paper=c,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null},D=a.el;C.prototype=D,D.constructor=C,a._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new C(c,b);d.type="path",z(d,{fill:"none",stroke:"#000",path:a});return d},D.rotate=function(a,b,e){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this.transform(this._.transform.concat([["r",a,b,e]]));return this},D.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]]));return this},D.translate=function(a,b){if(this.removed)return this;a=c(a).split(j),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this.transform(this._.transform.concat([["t",a,b]]));return this},D.transform=function(c){var d=this._;if(c==null)return d.transform;a._extractTransform(this,c),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&v(this),this.node&&q(this.node,{transform:this.matrix});if(d.sx!=1||d.sy!=1){var e=this.attrs[b]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},D.hide=function(){!this.removed&&this.paper.safari(this.node.style.display="none");return this},D.show=function(){!this.removed&&this.paper.safari(this.node.style.display="");return this},D.remove=function(){if(!this.removed){this.paper.__set__&&this.paper.__set__.exclude(this),k.unbind("*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node);for(var b in this)delete this[b];this.removed=!0}},D._getBBox=function(){if(this.node.style.display=="none"){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}a&&this.hide();return b},D.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c=="fill"&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;if(c=="transform")return this._.transform;var g=c.split(j),h={};for(var i=0,l=g.length;i<l;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return l-1?h:h[g[0]]}if(d==null&&a.is(c,"array")){h={};for(i=0,l=c.length;i<l;i++)h[c[i]]=this.attr(c[i]);return h}if(d!=null){var m={};m[c]=d}else c!=null&&a.is(c,"object")&&(m=c);for(var n in m)k("attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[b](n)&&m[b](n)&&a.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[b](p)&&(m[p]=o[p])}z(this,m);return this},D.toFront=function(){if(this.removed)return this;this.node.parentNode.appendChild(this.node);var b=this.paper;b.top!=this&&a._tofront(this,b);return this},D.toBack=function(){if(this.removed)return this;if(this.node.parentNode.firstChild!=this.node){this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper);var b=this.paper}return this},D.insertAfter=function(b){if(this.removed)return this;var c=b.node||b[b.length-1].node;c.nextSibling?c.parentNode.insertBefore(this.node,c.nextSibling):c.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},D.insertBefore=function(b){if(this.removed)return this;var c=b.node||b[0].node;c.parentNode.insertBefore(this.node,c),a._insertbefore(this,b,this.paper);return this},D.blur=function(b){var c=this;if(+b!==0){var d=q("filter"),e=q("feGaussianBlur");c.attrs.blur=b,d.id=a.createUUID(),q(e,{stdDeviation:+b||1.5}),d.appendChild(e),c.paper.defs.appendChild(d),c._blur=d,q(c.node,{filter:"url(#"+d.id+")"})}else c._blur&&(c._blur.parentNode.removeChild(c._blur),delete c._blur,delete c.attrs.blur),c.node.removeAttribute("filter")},a._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new C(e,a);f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs);return f},a._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new C(g,a);h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs);return h},a._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new C(f,a);g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs);return g},a._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new C(g,a);h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image";return h},a._engine.text=function(b,c,d,e){var f=q("text");b.canvas&&b.canvas.appendChild(f);var g=new C(f,b);g.attrs={x:c,y:d,"text-anchor":"middle",text:e,font:a._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",z(g,g.attrs);return g},a._engine.setSize=function(a,b){this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox);return this},a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b&&b.container,d=b.x,e=b.y,f=b.width,g=b.height;if(!c)throw new Error("SVG container not found.");var h=q("svg"),i="overflow:hidden;",j;d=d||0,e=e||0,f=f||512,g=g||342,q(h,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),c==1?(h.style.cssText=i+"position:absolute;left:"+d+"px;top:"+e+"px",a._g.doc.body.appendChild(h),j=1):(h.style.cssText=i+"position:relative",c.firstChild?c.insertBefore(h,c.firstChild):c.appendChild(h)),c=new a._Paper,c.width=f,c.height=g,c.canvas=h,c.clear(),c._left=c._top=0,j&&(c.renderfix=function(){}),c.renderfix();return c},a._engine.setViewBox=function(a,b,c,d,e){k("setViewBox",this,this._viewBox,[a,b,c,d,e]);var f=g(c/this.width,d/this.height),h=this.top,i=e?"meet":"xMinYMin",j,l;a==null?(this._vbSize&&(f=1),delete this._vbSize,j="0 0 "+this.width+m+this.height):(this._vbSize=f,j=a+m+b+m+c+m+d),q(this.canvas,{viewBox:j,preserveAspectRatio:i});while(f&&h)l="stroke-width"in h.attrs?h.attrs["stroke-width"]:1,h.attr({"stroke-width":l}),h._.dirty=1,h._.dirtyT=1,h=h.prev;this._viewBox=[a,b,c,d,!!e];return this},a.prototype.renderfix=function(){var a=this.canvas,b=a.style,c=a.getScreenCTM()||a.createSVGMatrix(),d=-c.e%1,e=-c.f%1;if(d||e)d&&(this._left=(this._left+d)%1,b.left=this._left+"px"),e&&(this._top=(this._top+e)%1,b.top=this._top+"px")},a.prototype.clear=function(){a.eve("clear",this);var b=this.canvas;while(b.firstChild)b.removeChild(b.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(a._g.doc.createTextNode("Created with Raphaël "+a.version)),b.appendChild(this.desc),b.appendChild(this.defs=q("defs"))},a.prototype.remove=function(){k("remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]=removed(a)};var E=a.st;for(var F in D)D[b](F)&&!E[b](F)&&(E[F]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(F))}(window.Raphael),window.Raphael.vml&&function(a){var b="hasOwnProperty",c=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=a.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(b){var d=/[ahqstv]/ig,e=a._pathToAbsolute;c(b).match(d)&&(e=a._path2curve),d=/[clmz]/g;if(e==a._pathToAbsolute&&!c(b).match(d)){var g=c(b).replace(q,function(a,b,c){var d=[],e=b.toLowerCase()=="m",g=p[b];c.replace(s,function(a){e&&d.length==2&&(g+=d+p[b=="m"?"l":"L"],d=[]),d.push(f(a*u))});return g+d});return g}var h=e(b),i,j;g=[];for(var k=0,l=h.length;k<l;k++){i=h[k],j=h[k][0].toLowerCase(),j=="z"&&(j="x");for(var m=1,r=i.length;m<r;m++)j+=f(i[m]*u)+(m!=r-1?",":o);g.push(j)}return g.join(n)},y=function(b,c,d){var e=a.matrix();e.rotate(-b,.5,.5);return{dx:e.x(c,d),dy:e.y(c,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q,r=u/b,s=u/c;m.visibility="hidden";if(!!b&&!!c){l.coordsize=i(r)+n+i(s),m.rotation=f*(b*c<0?-1:1);if(f){var t=y(f,d,e);d=t.dx,e=t.dy}b<0&&(p+="x"),c<0&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-r+n+e*-s;if(k||g.fillsize){var v=l.getElementsByTagName(j);v=v&&v[0],l.removeChild(v),k&&(t=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),v.position=t.dx*o+n+t.dy*o),g.fillsize&&(v.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(v)}m.visibility="visible"}};a.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running Raphaël "+this.version},addArrow=function(a,b,d){var e=c(b).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";while(g--)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},setFillAndStroke=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q,r=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),s=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),t=e;for(var y in i)i[b](y)&&(m[y]=i[y]);r&&(m.path=a._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur);if(i.path&&e.type=="path"||r)l.path=x(~c(m.path).toLowerCase().indexOf("r")?a._pathToAbsolute(m.path):m.path),e.type=="image"&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0));"transform"in i&&e.transform(i.transform);if(s){var A=+m.cx,C=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=a.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((A-D)*u),f((C-E)*u),f((A+D)*u),f((C+E)*u),f(A*u))}if("clip-rect"in i){var F=c(i["clip-rect"]).split(k);if(F.length==4){F[2]=+F[2]+ +F[0],F[3]=+F[3]+ +F[1];var G=l.clipRect||a._g.doc.createElement("div"),H=G.style;H.clip=a.format("rect({1}px {2}px {3}px {0}px)",F),l.clipRect||(H.position="absolute",H.top=0,H.left=0,H.width=e.paper.width+"px",H.height=e.paper.height+"px",l.parentNode.insertBefore(G,l),G.appendChild(l),l.clipRect=G)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip=o)}if(e.textpath){var I=e.textpath.style;i.font&&(I.font=i.font),i["font-family"]&&(I.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(I.fontSize=i["font-size"]),i["font-weight"]&&(I.fontWeight=i["font-weight"]),i["font-style"]&&(I.fontStyle=i["font-style"])}"arrow-start"in i&&addArrow(t,i["arrow-start"]),"arrow-end"in i&&addArrow(t,i["arrow-end"],1);if(i.opacity!=null||i["stroke-width"]!=null||i.fill!=null||i.src!=null||i.stroke!=null||i["stroke-width"]!=null||i["stroke-opacity"]!=null||i["fill-opacity"]!=null||i["stroke-dasharray"]!=null||i["stroke-miterlimit"]!=null||i["stroke-linejoin"]!=null||i["stroke-linecap"]!=null){var J=l.getElementsByTagName(j),K=!1;J=J&&J[0],!J&&(K=J=B(j)),e.type=="image"&&i.src&&(J.src=i.src),i.fill&&(J.on=!0);if(J.on==null||i.fill=="none"||i.fill===null)J.on=!1;if(J.on&&i.fill){var L=c(i.fill).match(a._ISURL);if(L){J.parentNode==l&&l.removeChild(J),J.rotate=!0,J.src=L[1],J.type="tile";var M=e.getBBox(1);J.position=M.x+n+M.y,e._.fillpos=[M.x,M.y],a._preload(L[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else J.color=a.getRGB(i.fill).hex,J.src=o,J.type="solid",a.getRGB(i.fill).error&&(t.type in{circle:1,ellipse:1}||c(i.fill).charAt()!="r")&&addGradientFill(t,i.fill,J)&&(m.fill="none",m.gradient=i.fill,J.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var N=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+a.getRGB(i.fill).o+1||2)-1);N=h(g(N,0),1),J.opacity=N,J.src&&(J.color="none")}l.appendChild(J);var O=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],P=!1;!O&&(P=O=B("stroke"));if(i.stroke&&i.stroke!="none"||i["stroke-width"]||i["stroke-opacity"]!=null||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])O.on=!0;(i.stroke=="none"||i.stroke===null||O.on==null||i.stroke==0||i["stroke-width"]==0)&&(O.on=!1);var Q=a.getRGB(i.stroke);O.on&&i.stroke&&(O.color=Q.hex),N=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+Q.o+1||2)-1);var T=(d(i["stroke-width"])||1)*.75;N=h(g(N,0),1),i["stroke-width"]==null&&(T=m["stroke-width"]),i["stroke-width"]&&(O.weight=T),T&&T<1&&(N*=T)&&(O.weight=1),O.opacity=N,i["stroke-linejoin"]&&(O.joinstyle=i["stroke-linejoin"]||"miter"),O.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(O.endcap=i["stroke-linecap"]=="butt"?"flat":i["stroke-linecap"]=="square"?"square":"round");if(i["stroke-dasharray"]){var U={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};O.dashstyle=U[b](i["stroke-dasharray"])?U[i["stroke-dasharray"]]:o}P&&l.appendChild(O)}if(t.type=="text"){t.paper.canvas.style.display=o;var V=t.paper.span,W=100,X=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=V.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),X=d(X?X[0]:m["font-size"]),p.fontSize=X*W+"px",t.textpath.string&&(V.innerHTML=c(t.textpath.string).replace(/</g,"&#60;").replace(/&/g,"&#38;").replace(/\n/g,"<br>"));var Y=V.getBoundingClientRect();t.W=m.w=(Y.right-Y.left)/W,t.H=m.h=(Y.bottom-Y.top)/W,t.X=m.x,t.Y=m.y+t.H/2,("x"in i||"y"in i)&&(t.path.v=a.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));var Z=["x","y","text","font","font-family","font-weight","font-style","font-size"];for(var $=0,_=Z.length;$<_;$++)if(Z[$]in i){t._.dirty=1;break}switch(m["text-anchor"]){case"start":t.textpath.style["v-text-align"]="left",t.bbx=t.W/2;break;case"end":t.textpath.style["v-text-align"]="right",t.bbx=-t.W/2;break;default:t.textpath.style["v-text-align"]="center",t.bbx=0}t.textpath.style["v-text-kern"]=!0}},addGradientFill=function(b,f,g){b.attrs=b.attrs||{};var h=b.attrs,i=Math.pow,j,k,l="linear",m=".5 .5";b.attrs.gradient=f,f=c(f).replace(a._radial_gradient,function(a,b,c){l="radial",b&&c&&(b=d(b),c=d(c),i(b-.5,2)+i(c-.5,2)>.25&&(c=e.sqrt(.25-i(b-.5,2))*((c>.5)*2-1)+.5),m=b+n+c);return o}),f=f.split(/\s*\-\s*/);if(l=="linear"){var p=f.shift();p=-d(p);if(isNaN(p))return null}var q=a._parseDots(f);if(!q)return null;b=b.shape||b.node;if(q.length){b.removeChild(g),g.on=!0,g.method="none",g.color=q[0].color,g.color2=q[q.length-1].color;var r=[];for(var s=0,t=q.length;s<t;s++)q[s].offset&&r.push(q[s].offset+n+q[s].color);g.colors=r.length?r.join():"0% "+g.color,l=="radial"?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=m,g.angle=0):(g.type="gradient",g.angle=(270-p)%360),b.appendChild(g)}return 1},Element=function(b,c){this[0]=this.node=b,b.raphael=!0,this.id=a._oid++,b.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=c,this.matrix=a.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!c.bottom&&(c.bottom=this),this.prev=c.top,c.top&&(c.top.next=this),c.top=this,this.next=null};var A=a.el;Element.prototype=A,A.constructor=Element,A.transform=function(b){if(b==null)return this._.transform;var d=this.paper._viewBoxShift,e=d?"s"+[d.scale,d.scale]+"-1-1t"+[d.dx,d.dy]:o,f;d&&(f=b=c(b).replace(/\.{3}|\u2026/g,this._.transform||o)),a._extractTransform(this,e+b);var g=this.matrix.clone(),h=this.skew,i=this.node,j,k=~c(this.attrs.fill).indexOf("-"),l=!c(this.attrs.fill).indexOf("url(");g.translate(-0.5,-0.5);if(l||k||this.type=="image"){h.matrix="1 0 0 1",h.offset="0 0",j=g.split();if(k&&j.noRotation||!j.isSimple){i.style.filter=g.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;i.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else i.style.filter=o,z(this,j.scalex,j.scaley,j.dx,j.dy,j.rotate)}else i.style.filter=o,h.matrix=c(g),h.offset=g.offset();f&&(this._.transform=f);return this},A.rotate=function(a,b,e){if(this.removed)return this;if(a!=null){a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2])),a=d(a[0]),e==null&&(b=e);if(b==null||e==null){var f=this.getBBox(1);b=f.x+f.width/2,e=f.y+f.height/2}this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,b,e]]));return this}},A.translate=function(a,b){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1])),a=d(a[0])||0,b=+b||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=b),this.transform(this._.transform.concat([["t",a,b]]));return this},A.scale=function(a,b,e,f){if(this.removed)return this;a=c(a).split(k),a.length-1&&(b=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),b==null&&(b=a),f==null&&(e=f);if(e==null||f==null)var g=this.getBBox(1);e=e==null?g.x+g.width/2:e,f=f==null?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,b,e,f]])),this._.dirtyT=1;return this},A.hide=function(){!this.removed&&(this.node.style.display="none");return this},A.show=function(){!this.removed&&(this.node.style.display=o);return this},A._getBBox=function(){if(this.removed)return{};return this.type=="text"?{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}:pathDimensions(this.attrs.path)},A.remove=function(){if(!this.removed){this.paper.__set__&&this.paper.__set__.exclude(this),a.eve.unbind("*.*."+this.id),a._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var b in this)delete this[b];this.removed=!0}},A.attr=function(c,d){if(this.removed)return this;if(c==null){var e={};for(var f in this.attrs)this.attrs[b](f)&&(e[f]=this.attrs[f]);e.gradient&&e.fill=="none"&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform;return e}if(d==null&&a.is(c,"string")){if(c==j&&this.attrs.fill=="none"&&this.attrs.gradient)return this.attrs.gradient;var g=c.split(k),h={};for(var i=0,m=g.length;i<m;i++)c=g[i],c in this.attrs?h[c]=this.attrs[c]:a.is(this.paper.customAttributes[c],"function")?h[c]=this.paper.customAttributes[c].def:h[c]=a._availableAttrs[c];return m-1?h:h[g[0]]}if(this.attrs&&d==null&&a.is(c,"array")){h={};for(i=0,m=c.length;i<m;i++)h[c[i]]=this.attr(c[i]);return h}var n;d!=null&&(n={},n[c]=d),d==null&&a.is(c,"object")&&(n=c);for(var o in n)l("attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[b](o)&&n[b](o)&&a.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[b](q)&&(n[q]=p[q])}n.text&&this.type=="text"&&(this.textpath.string=n.text),setFillAndStroke(this,n)}return this},A.toFront=function(){!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&a._tofront(this,this.paper);return this},A.toBack=function(){if(this.removed)return this;this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),a._toback(this,this.paper));return this},A.insertAfter=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[b.length-1]),b.node.nextSibling?b.node.parentNode.insertBefore(this.node,b.node.nextSibling):b.node.parentNode.appendChild(this.node),a._insertafter(this,b,this.paper);return this},A.insertBefore=function(b){if(this.removed)return this;b.constructor==a.st.constructor&&(b=b[0]),b.node.parentNode.insertBefore(this.node,b.node),a._insertbefore(this,b,this.paper);return this},A.blur=function(b){var c=this.node.runtimeStyle,d=c.filter;d=d.replace(r,o),+b!==0?(this.attrs.blur=b,c.filter=d+n+m+".Blur(pixelradius="+(+b||1.5)+")",c.margin=a.format("-{0}px 0 0 -{0}px",f(+b||1.5))):(c.filter=d,c.margin=0,delete this.attrs.blur)},a._engine.path=function(a,b){var c=B("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new Element(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,setFillAndStroke(d,e),b.canvas.appendChild(c);var f=B("skew");f.on=!0,c.appendChild(f),d.skew=f,d.transform(o);return d},a._engine.rect=function(b,c,d,e,f,g){var h=a._rectPath(c,d,e,f,g),i=b.path(h),j=i.attrs;i.X=j.x=c,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect";return i},a._engine.ellipse=function(a,b,c,d,e){var f=a.path(),g=f.attrs;f.X=b-d,f.Y=c-e,f.W=d*2,f.H=e*2,f.type="ellipse",setFillAndStroke(f,{cx:b,cy:c,rx:d,ry:e});return f},a._engine.circle=function(a,b,c,d){var e=a.path(),f=e.attrs;e.X=b-d,e.Y=c-d,e.W=e.H=d*2,e.type="circle",setFillAndStroke(e,{cx:b,cy:c,r:d});return e},a._engine.image=function(b,c,d,e,f,g){var h=a._rectPath(d,e,f,g),i=b.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];k.src=c,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=c,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0);return i},a._engine.text=function(b,d,e,g){var h=B("shape"),i=B("path"),j=B("textpath");d=d||0,e=e||0,g=g||"",i.v=a.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=c(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new Element(h,b),l={fill:"#000",stroke:"none",font:a._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=c(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,setFillAndStroke(k,l),h.appendChild(j),h.appendChild(i),b.canvas.appendChild(h);var m=B("skew");m.on=!0,h.appendChild(m),k.skew=m,k.transform(o);return k},a._engine.setSize=function(a,b){var c=this.canvas.style;this.width=a,this.height=b,a==+a&&(a+="px"),b==+b&&(b+="px"),c.width=a,c.height=b,c.clip="rect(0 "+a+" "+b+" 0)",this._viewBox&&setViewBox.apply(this,this._viewBox);return this},a._engine.setViewBox=function(b,c,d,e,f){a.eve("setViewBox",this,this._viewBox,[b,c,d,e,f]);var h=this.width,i=this.height,j=1/g(d/h,e/i),k,l;f&&(k=i/e,l=h/d,d*k<h&&(b-=(h-d*k)/2/k),e*l<i&&(c-=(i-e*l)/2/l)),this._viewBox=[b,c,d,e,!!f],this._viewBoxShift={dx:-b,dy:-c,scale:j},this.forEach(function(a){a.transform("...")});return this};var B,C=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),B=function(a){return b.createElement("<rvml:"+a+' class="rvml">')}}catch(c){B=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}};C(a._g.win),a._engine.create=function(){var b=a._getContainer.apply(0,arguments),c=b.container,d=b.height,e,f=b.width,g=b.x,h=b.y;if(!c)throw new Error("VML container not found.");var i=new a._Paper,j=i.canvas=a._g.doc.createElement("div"),k=j.style;g=g||0,h=h||0,f=f||512,d=d||342,i.width=f,i.height=d,f==+f&&(f+="px"),d==+d&&(d+="px"),i.coordsize=u*1e3+n+u*1e3,i.coordorigin="0 0",i.span=a._g.doc.createElement("span"),i.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",j.appendChild(i.span),k.cssText=a.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",f,d),c==1?(a._g.doc.body.appendChild(j),k.left=g+"px",k.top=h+"px",k.position="absolute"):c.firstChild?c.insertBefore(j,c.firstChild):c.appendChild(j),i.renderfix=function(){};return i},a.prototype.clear=function(){a.eve("clear",this),this.canvas.innerHTML=o,this.span=a._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},a.prototype.remove=function(){a.eve("remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var b in this)this[b]=removed(b);return!0};var D=a.st;for(var E in A)A[b](E)&&!D[b](E)&&(D[E]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(E))}(window.Raphael) \ No newline at end of file
diff --git a/addons/web_diagram/static/src/css/base_diagram.css b/addons/web_diagram/static/src/css/base_diagram.css
index 9ba2f6b0c83..0dd8483fdc4 100644
--- a/addons/web_diagram/static/src/css/base_diagram.css
+++ b/addons/web_diagram/static/src/css/base_diagram.css
@@ -1,13 +1,3 @@
-.openerp .diagram {
- border: 1px solid #999;
- -moz-border-radius: 8px;
- -webkit-border-radius: 8px;
-}
-
-.openerp .show_grid {
- background: url("/web_diagram/static/src/img/grid.jpg") repeat;
-}
-
.openerp .oe_diagram_pager {
text-align: right;
white-space: nowrap;
diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js
index b4aa62fd8f0..e4fb3ef5b75 100644
--- a/addons/web_diagram/static/src/js/diagram.js
+++ b/addons/web_diagram/static/src/js/diagram.js
@@ -4,7 +4,6 @@
openerp.web_diagram = function (openerp) {
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_diagram/static/src/xml/base_diagram.xml');
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
openerp.web.DiagramView = openerp.web.View.extend({
searchable: false,
@@ -54,11 +53,6 @@ openerp.web.DiagramView = openerp.web.View.extend({
// New Node,Edge
this.$element.find('#new_node.oe_diagram_button_new').click(function(){self.add_edit_node(null, self.node);});
- this.$element.find('#new_edge.oe_diagram_button_new').click(function(){self.add_edit_node(null, self.connector);});
-
- this.$element.find('#toggle_grid').click(function() {
- self.$element.find('.diagram').toggleClass('show_grid');
- });
if(this.id) {
self.get_diagram_info();
@@ -113,8 +107,25 @@ openerp.web.DiagramView = openerp.web.View.extend({
this.get_diagram_info();
}
},
-
+ select_node: function (node, element) {
+ if (!this.selected_node) {
+ this.selected_node = node;
+ element.attr('stroke', 'red');
+ return;
+ }
+ // Re-click selected node, deselect it
+ if (node.id === this.selected_node.id) {
+ this.selected_node = null;
+ element.attr('stroke', 'black');
+ return;
+ }
+ this.add_edit_node(null, this.connector, {
+ act_from: this.selected_node.id,
+ act_to: node.id
+ });
+ },
draw_diagram: function(result) {
+ this.selected_node = null;
var diagram = new Graph();
this.active_model = result['id_model'];
@@ -125,34 +136,33 @@ openerp.web.DiagramView = openerp.web.View.extend({
//Custom logic
var self = this;
var renderer = function(r, n) {
- var node;
- var set;
- var shape = n.node.shape;
- if(shape == 'rectangle')
- shape = 'rect';
- node = r[shape](n.node.x, n.node.y).attr({
+ var shape = (n.node.shape === 'rectangle') ? 'rect' : 'ellipse';
+
+ var node = r[shape](n.node.x, n.node.y).attr({
"fill": n.node.color
- }).dblclick(function() {
- self.add_edit_node(n.node.id, self.node);
});
- set = r.set()
- .push(node)
- .push(
- r.text(n.node.x, n.node.y, (n.label || n.id))
- .attr({"cursor":"pointer"})
- .dblclick(function() {
- self.add_edit_node(n.node.id, self.node);
- })
- );
- node.attr({cursor: "pointer"});
-
- if(shape == "ellipse")
- node.attr({rx: "40", ry: "20"});
- else if(shape == 'rect') {
+
+ var nodes = r.set(node, r.text(n.node.x, n.node.y, (n.label || n.id)))
+ .attr("cursor", "pointer")
+ .dblclick(function() {
+ self.add_edit_node(n.node.id, self.node);
+ })
+ .mousedown(function () { node.moved = false; })
+ .mousemove(function () { node.moved = true; })
+ .click(function () {
+ // Ignore click from move event
+ if (node.moved) { return; }
+ self.select_node(n.node, node);
+ });
+
+ if (shape === 'rect') {
node.attr({width: "60", height: "44"});
node.next.attr({"text-anchor": "middle", x: n.node.x + 20, y: n.node.y + 20});
+ } else {
+ node.attr({rx: "40", ry: "20"});
}
- return set;
+
+ return nodes;
};
_.each(res_nodes, function(res_node) {
@@ -167,10 +177,7 @@ openerp.web.DiagramView = openerp.web.View.extend({
diagram.addEdge(connector['source'], connector['destination'], {directed : true, label: connector['signal']});
});
-
- if ($('div#dia-canvas').children().length > 0) {
- $('div#dia-canvas').children().remove();
- }
+ self.$element.find('.diagram').empty();
var layouter = new Graph.Layout.Ordered(diagram);
var render_diagram = new Graph.Renderer.Raphael('dia-canvas', diagram, $('div#dia-canvas').width(), $('div#dia-canvas').height());
@@ -184,7 +191,8 @@ openerp.web.DiagramView = openerp.web.View.extend({
});
},
- add_edit_node: function(id, model) {
+ add_edit_node: function(id, model, defaults) {
+ defaults = defaults || {};
var self = this;
if(!model)
@@ -253,6 +261,15 @@ openerp.web.DiagramView = openerp.web.View.extend({
});
});
}
+ if (!_.isEmpty(defaults)) {
+ form_controller.on_record_loaded.add_last(function () {
+ _(form_fields).each(function (field) {
+ if (!defaults[field]) { return; }
+ form_controller.fields[field].set_value(defaults[field]);
+ form_controller.fields[field].dirty = true;
+ });
+ });
+ }
},
on_pager_action: function(action) {
diff --git a/addons/web_diagram/static/src/xml/base_diagram.xml b/addons/web_diagram/static/src/xml/base_diagram.xml
index 7867befa957..20613c7b079 100644
--- a/addons/web_diagram/static/src/xml/base_diagram.xml
+++ b/addons/web_diagram/static/src/xml/base_diagram.xml
@@ -3,8 +3,6 @@
<div class="oe_diagram_header" t-att-id="element_id + '_header'">
<div class="oe_diagram_buttons">
<button type="button" id="new_node" class="oe_diagram_button_new">New Node</button>
- <button type="button" id="new_edge" class="oe_diagram_button_new">New Edge</button>
- <label>Show Grid:</label><input type="checkbox" id="toggle_grid" checked="checked"/>
</div>
<div class="oe_diagram_pager">
<button type="button" data-pager-action="first">First</button>
@@ -16,6 +14,6 @@
<button type="button" data-pager-action="last">Last</button>
</div>
</div>
- <div id="dia-canvas" class="diagram show_grid" style="overflow: auto;"></div>
+ <div id="dia-canvas" class="diagram" style="overflow: auto;"></div>
</t>
</template>
diff --git a/addons/web_gantt/__openerp__.py b/addons/web_gantt/__openerp__.py
index d2b24f96d08..cd24a8f7314 100644
--- a/addons/web_gantt/__openerp__.py
+++ b/addons/web_gantt/__openerp__.py
@@ -9,5 +9,8 @@
'static/src/js/gantt.js'
],
"css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
'active': True
}
diff --git a/addons/web_gantt/static/src/js/gantt.js b/addons/web_gantt/static/src/js/gantt.js
index 73e244edad7..d2eb3aed899 100644
--- a/addons/web_gantt/static/src/js/gantt.js
+++ b/addons/web_gantt/static/src/js/gantt.js
@@ -3,7 +3,6 @@
*---------------------------------------------------------*/
openerp.web_gantt = function (openerp) {
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_gantt/static/src/xml/web_gantt.xml');
openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView');
openerp.web_gantt.GanttView = openerp.web.View.extend({
@@ -43,7 +42,7 @@ init: function(parent, dataset, view_id) {
this.name = this.fields_view.arch.attrs.string;
this.view_id = this.fields_view.view_id;
-
+
this.date_start = this.fields_view.arch.attrs.date_start;
this.date_delay = this.fields_view.arch.attrs.date_delay;
this.date_stop = this.fields_view.arch.attrs.date_stop;
@@ -71,7 +70,7 @@ init: function(parent, dataset, view_id) {
ganttChartControl.setImagePath("/web_gantt/static/lib/dhtmlxGantt/codebase/imgs/");
ganttChartControl.setEditable(true);
ganttChartControl.showTreePanel(true);
- ganttChartControl.showContextMenu(true);
+ ganttChartControl.showContextMenu(false);
ganttChartControl.showDescTask(true,'d,s-f');
ganttChartControl.showDescProject(true,'n,d');
@@ -228,7 +227,7 @@ init: function(parent, dataset, view_id) {
var evt_date = "";
var evt_duration = "";
var evt_end_date = "";
-
+ var project_tree_field = [];
for (var i in final_events){
evt_id = final_events[i];
evt_date = all_events[evt_id]['evt'][2];
@@ -254,7 +253,7 @@ init: function(parent, dataset, view_id) {
self.render_events(all_events, 0);
}
- for (var i in final_events){
+ for (var i in final_events) {
evt_id = final_events[i];
res = all_events[evt_id];
task=new GanttTaskInfo(res['evt'][0], res['evt'][1], res['evt'][2], res['evt'][3], res['evt'][4], "",res['evt'][6]);
@@ -278,8 +277,9 @@ init: function(parent, dataset, view_id) {
ganttChartControl.attachEvent("onTaskStartDrag", function(task) {self.on_drag_start(task);});
ganttChartControl.attachEvent("onTaskEndResize", function(task) {self.on_resize_drag_end(task, "resize");});
ganttChartControl.attachEvent("onTaskEndDrag", function(task) {self.on_resize_drag_end(task, "drag");});
+
ganttChartControl.attachEvent("onTaskDblClick", function(task) {self.open_popup(task);});
-
+
var taskdiv = jQuery("div.taskPanel").parent();
taskdiv.addClass('ganttTaskPanel');
taskdiv.prev().addClass('ganttDayPanel');
@@ -293,7 +293,7 @@ init: function(parent, dataset, view_id) {
self.set_width();
});
- jQuery(window).bind('resize',function(){
+ jQuery(window).bind('resize',function() {
window.clearTimeout(ganttChartControl._resize_timer);
ganttChartControl._resize_timer = window.setTimeout(function(){
self.reload_gantt();
@@ -385,53 +385,46 @@ init: function(parent, dataset, view_id) {
},
open_popup : function(task) {
+ var self = this;
var event_id = task.getId();
if(event_id.toString().search("_") != -1)
return;
if(event_id) event_id = parseInt(event_id, 10);
-
- var action = {
- "res_model": this.dataset.model,
- "res_id": event_id,
- "views":[[false,"form"]],
- "type":"ir.actions.act_window",
- "view_type":"form",
- "view_mode":"form"
- };
-
- action.flags = {
- search_view: false,
- sidebar : false,
- views_switcher : false,
- pager: false
- };
- var element_id = _.uniqueId("act_window_dialog");
- var dialog = jQuery('<div>', {
- 'id': element_id
- }).dialog({
- modal: true,
- width: 'auto',
- height: 'auto',
- buttons: {
- Cancel: function() {
- $(this).dialog("destroy");
- },
- Save: function() {
- var view_manager = action_manager.viewmanager;
- var _dialog = this;
- view_manager.views[view_manager.active_view].controller.do_save(function(r) {
- $(_dialog).dialog("destroy");
- self.reload_gantt();
- })
- }
+
+ var action_manager = new openerp.web.ActionManager(this);
+
+ var dialog = new openerp.web.Dialog(this, {
+ width: 800,
+ height: 600,
+ buttons : {
+ Cancel : function() {
+ $(this).dialog('destroy');
+ },
+ Save : function() {
+ var form_view = action_manager.inner_viewmanager.views.form.controller;
+
+ form_view.do_save(function() {
+ self.get_events();
+ });
+ $(this).dialog('destroy');
}
+ }
+ }).start().open();
+ action_manager.appendTo(dialog.$element);
+ action_manager.do_action({
+ res_model : this.dataset.model,
+ res_id: event_id,
+ views : [[false, 'form']],
+ type : 'ir.actions.act_window',
+ auto_search : false,
+ flags : {
+ search_view: false,
+ sidebar : false,
+ views_switcher : false,
+ action_buttons : false,
+ pager: false
+ }
});
- var action_manager = new openerp.web.ActionManager(this, element_id);
- action_manager.start();
- action_manager.do_action(action);
-
- //Default_get
- if(!event_id) action_manager.viewmanager.dataset.index = null;
},
on_drag_start : function(task){
diff --git a/addons/web_graph/__openerp__.py b/addons/web_graph/__openerp__.py
index 68775b7c0e3..d7c37acb180 100644
--- a/addons/web_graph/__openerp__.py
+++ b/addons/web_graph/__openerp__.py
@@ -7,5 +7,8 @@
"static/lib/dhtmlxGraph/codebase/dhtmlxchart_debug.js",
"static/src/js/graph.js"],
"css": ["static/lib/dhtmlxGraph/codebase/dhtmlxchart.css"],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
"active": True
}
diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js
index bac147b1a91..04e9d77f5d0 100644
--- a/addons/web_graph/static/src/js/graph.js
+++ b/addons/web_graph/static/src/js/graph.js
@@ -13,7 +13,6 @@ var COLOR_PALETTE = [
'#cc0000', '#d400a8'];
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_graph/static/src/xml/web_graph.xml');
openerp.web.views.add('graph', 'openerp.web_graph.GraphView');
openerp.web_graph.GraphView = openerp.web.View.extend({
@@ -29,6 +28,14 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
this.columns = [];
this.group_field = null;
this.is_loaded = $.Deferred();
+
+ this.renderer = null;
+ },
+ stop: function () {
+ if (this.renderer) {
+ clearTimeout(this.renderer);
+ }
+ this._super();
},
do_show: function () {
this.$element.show();
@@ -256,90 +263,113 @@ openerp.web_graph.GraphView = openerp.web.View.extend({
x_axis = abscissa_description;
y_axis = ordinate_description;
}
-
- var bar_chart = new dhtmlXChart({
- view: view_chart,
- container: this.element_id+"-barchart",
- value:"#"+group_list[0].group+"#",
- gradient: "3d",
- border: false,
- width: 1024,
- tooltip:{
- template: _.sprintf("#%s#, %s=#%s#",
- this.abscissa, group_list[0].text, group_list[0].group)
- },
- radius: 0,
- color:group_list[0].color,
- origin:0,
- xAxis: x_axis,
- yAxis: y_axis,
- padding: {
- left: 75
- },
- legend: {
- values: group_list,
- align:"left",
- valign:"top",
- layout: "x",
- marker: {
- type:"round",
- width:12
- }
+
+ var renderer = function () {
+ if (self.$element.is(':hidden')) {
+ self.renderer = setTimeout(renderer, 100);
+ return;
}
- });
- for (var m = 1; m<group_list.length;m++){
- var column = group_list[m];
- if (column.group === this.group_field) { continue; }
- bar_chart.addSeries({
- value: "#"+column.group+"#",
+ self.renderer = null;
+ var bar_chart = new dhtmlXChart({
+ view: view_chart,
+ container: self.element_id+"-barchart",
+ value:"#"+group_list[0].group+"#",
+ gradient: "3d",
+ border: false,
+ width: 1024,
tooltip:{
template: _.sprintf("#%s#, %s=#%s#",
- this.abscissa, column.text, column.group)
+ self.abscissa, group_list[0].text, group_list[0].group)
+ },
+ radius: 0,
+ color:group_list[0].color,
+ origin:0,
+ xAxis: x_axis,
+ yAxis: y_axis,
+ padding: {
+ left: 75
},
- color: column.color
+ legend: {
+ values: group_list,
+ align:"left",
+ valign:"top",
+ layout: "x",
+ marker: {
+ type:"round",
+ width:12
+ }
+ }
+ });
+ for (var m = 1; m<group_list.length;m++){
+ var column = group_list[m];
+ if (column.group === self.group_field) { continue; }
+ bar_chart.addSeries({
+ value: "#"+column.group+"#",
+ tooltip:{
+ template: _.sprintf("#%s#, %s=#%s#",
+ self.abscissa, column.text, column.group)
+ },
+ color: column.color
+ });
+ }
+ bar_chart.parse(results, "json");
+ self.$element.find("#"+self.element_id+"-barchart").height(
+ self.$element.find("#"+self.element_id+"-barchart").height()+50);
+ bar_chart.attachEvent("onItemClick", function(id) {
+ self.open_list_view(bar_chart.get(id));
});
+ };
+ if (this.renderer) {
+ clearTimeout(this.renderer);
}
- bar_chart.parse(results, "json");
- jQuery("#"+this.element_id+"-barchart").height(jQuery("#"+this.element_id+"-barchart").height()+50);
- bar_chart.attachEvent("onItemClick", function(id) {
- self.open_list_view(bar_chart.get(id));
- });
+ this.renderer = setTimeout(renderer, 0);
},
schedule_pie: function(result) {
var self = this;
- var chart = new dhtmlXChart({
- view:"pie3D",
- container:self.element_id+"-piechart",
- value:"#"+self.ordinate+"#",
- pieInnerText:function(obj) {
- var sum = chart.sum("#"+self.ordinate+"#");
- var val = obj[self.ordinate] / sum * 100 ;
- return val.toFixed(1) + "%";
- },
- tooltip:{
- template:"#"+self.abscissa+"#"+"="+"#"+self.ordinate+"#"
- },
- gradient:"3d",
- height: 20,
- radius: 200,
- legend: {
- width: 300,
- align:"left",
- valign:"top",
- layout: "x",
- marker:{
- type:"round",
- width:12
+ var renderer = function () {
+ if (self.$element.is(':hidden')) {
+ self.renderer = setTimeout(renderer, 100);
+ return;
+ }
+ self.renderer = null;
+ var chart = new dhtmlXChart({
+ view:"pie3D",
+ container:self.element_id+"-piechart",
+ value:"#"+self.ordinate+"#",
+ pieInnerText:function(obj) {
+ var sum = chart.sum("#"+self.ordinate+"#");
+ var val = obj[self.ordinate] / sum * 100 ;
+ return val.toFixed(1) + "%";
},
- template:function(obj){
- return obj[self.abscissa] || 'Undefined';
+ tooltip:{
+ template:"#"+self.abscissa+"#"+"="+"#"+self.ordinate+"#"
+ },
+ gradient:"3d",
+ height: 20,
+ radius: 200,
+ legend: {
+ width: 300,
+ align:"left",
+ valign:"top",
+ layout: "x",
+ marker:{
+ type:"round",
+ width:12
+ },
+ template:function(obj){
+ return obj[self.abscissa] || 'Undefined';
+ }
}
- }
- });
- chart.parse(result,"json");
- chart.attachEvent("onItemClick", function(id) {
- self.open_list_view(chart.get(id));
- });
+ });
+ chart.parse(result,"json");
+ chart.attachEvent("onItemClick", function(id) {
+ self.open_list_view(chart.get(id));
+ });
+ };
+ if (this.renderer) {
+ clearTimeout(this.renderer);
+ }
+ this.renderer = setTimeout(renderer, 0);
},
open_list_view : function (id){
var self = this;
diff --git a/addons/web_kanban/__openerp__.py b/addons/web_kanban/__openerp__.py
index f39cd64999b..92d60b0f4ed 100644
--- a/addons/web_kanban/__openerp__.py
+++ b/addons/web_kanban/__openerp__.py
@@ -9,5 +9,8 @@
"css": [
"static/src/css/kanban.css"
],
+ 'qweb' : [
+ "static/src/xml/*.xml",
+ ],
'active': True
}
diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css
index 82143e460d1..6c6ddd57dec 100644
--- a/addons/web_kanban/static/src/css/kanban.css
+++ b/addons/web_kanban/static/src/css/kanban.css
@@ -1,36 +1,71 @@
-.openerp .oe_kanban_view .oe_column {
- width: 100%;
-}
-
-.openerp .oe_vertical_text {
- writing-mode:tb-rl;
- -webkit-transform:rotate(90deg);
- -moz-transform:rotate(90deg);
- -o-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- transform: rotate(90deg);
- display:block;
- width:30px;
- height:20px;
- align:center;
- font-size:24px;
-}
-
.openerp .oe_kanban_view .ui-sortable-placeholder {
border: 1px dotted black;
visibility: visible !important;
height: 60px !important;
}
+.openerp .oe_kanban_group_header {
+ position: relative;
+}
+.openerp .oe_kanban_group_folded {
+ padding: 0 5px 0 5px;
+}
+.openerp .oe_kanban_group_folded .oe_kanban_group_title,
+.openerp .oe_kanban_group_folded .oe_kanban_aggregates {
+ display: none;
+}
+.openerp .oe_kanban_group_folded .oe_kanban_group_title_vertical {
+ display: block;
+}
-.openerp .oe_kanban_view .oe_column_heading {
+.openerp .oe_kanban_group_title {
color: #000000;
- font-size: 1.5em;
+ font-size: 130%;
font-weight: bold;
}
-.openerp .oe_kanban_view .fold-columns-icon {
+.openerp .oe_kanban_group_title_undefined {
+ color: #666666;
+}
+.openerp .oe_kanban_group_title_vertical {
+ writing-mode: tb-rl;
+ -webkit-transform: rotate(90deg);
+ -moz-transform: rotate(90deg);
+ -o-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+ width: 30px;
+ height: 20px;
+ align: center;
+ font-size: 24px;
+ white-space: nowrap;
+ display: none;
+ position: absolute;
+ top: 10px;
+}
+
+.openerp .oe_kanban_fold_icon {
+ cursor: pointer;
float: left;
padding: 2px 2px 0 0;
+ width: 16px;
+ height: 16px;
+ background: url(/web_kanban/static/src/img/minus-icon.png) no-repeat;
+}
+.openerp .oe_kanban_group_folded .oe_kanban_fold_icon {
+ background: url(/web_kanban/static/src/img/plus-icon.png) no-repeat;
+}
+
+.openerp ul.oe_kanban_aggregates {
+ padding: 0;
+ margin: 0 0 0 22px;
}
+.openerp ul.oe_kanban_aggregates li {
+ list-style: circle;
+ font-style: italic;
+}
+.openerp ul.oe_kanban_aggregates span {
+ text-decoration: underline;
+}
+
.openerp .oe_kanban_action_button {
height: 22px;
margin: 0;
@@ -50,17 +85,17 @@
border-bottom: 1px solid #CCC;
}
.openerp .oe_kanban_title1 {
- font-size: 130%;
+ font-size: 120%;
font-weight: bold;
padding: 0 4px 0 4px;
}
.openerp .oe_kanban_title2 {
- font-size: 120%;
+ font-size: 110%;
font-weight: bold;
padding: 0 4px 0 4px;
}
.openerp .oe_kanban_title3 {
- font-size: 110%;
+ font-size: 100%;
font-weight: normal;
padding: 0 4px 0 4px;
}
@@ -87,6 +122,7 @@
white-space: nowrap;
padding-top: 2px;
position: relative;
+ clear: both;
}
.openerp .oe_kanban_buttons_set a {
padding: 2px;
@@ -132,91 +168,113 @@
}
/* Custom colors are also present in kanban.js */
+/* Custom color#0 */
+.openerp .oe_kanban_color_0 .oe_kanban_color_bglight {
+ background: #FFFFFF;
+}
+.openerp .oe_kanban_color_0 .oe_kanban_color_bgdark {
+ background: #EEEEEE;
+}
+.openerp .oe_kanban_color_0 .oe_kanban_color_border {
+ border-color: #CCCCCC;
+}
+
/* Custom color#1 */
.openerp .oe_kanban_color_1 .oe_kanban_color_bglight {
- background: #FFC7C7;
+ background: #CCCCCC;
}
.openerp .oe_kanban_color_1 .oe_kanban_color_bgdark {
- background: #FF8F8F;
+ background: #999999;
}
.openerp .oe_kanban_color_1 .oe_kanban_color_border {
- border-color: #D97979;
+ border-color: #666666;
}
/* Custom color#2 */
.openerp .oe_kanban_color_2 .oe_kanban_color_bglight {
- background: #FFF1C7;
+ background: #FFC7C7;
}
.openerp .oe_kanban_color_2 .oe_kanban_color_bgdark {
- background: #FFE38F;
+ background: #FF8F8F;
}
.openerp .oe_kanban_color_2 .oe_kanban_color_border {
- border-color: #D9C179;
+ border-color: #D97979;
}
/* Custom color#3 */
.openerp .oe_kanban_color_3 .oe_kanban_color_bglight {
- background: #E3FFC7;
+ background: #FFF1C7;
}
.openerp .oe_kanban_color_3 .oe_kanban_color_bgdark {
- background: #C7FF8F;
+ background: #FFE38F;
}
.openerp .oe_kanban_color_3 .oe_kanban_color_border {
- border-color: #A9D979;
+ border-color: #D9C179;
}
/* Custom color#4 */
.openerp .oe_kanban_color_4 .oe_kanban_color_bglight {
- background: #C7FFD5;
+ background: #E3FFC7;
}
.openerp .oe_kanban_color_4 .oe_kanban_color_bgdark {
- background: #8FFFAB;
+ background: #C7FF8F;
}
.openerp .oe_kanban_color_4 .oe_kanban_color_border {
- border-color: #79D991;
+ border-color: #A9D979;
}
/* Custom color#5 */
.openerp .oe_kanban_color_5 .oe_kanban_color_bglight {
- background: #C7FFFF;
+ background: #C7FFD5;
}
.openerp .oe_kanban_color_5 .oe_kanban_color_bgdark {
- background: #8FFFFF;
+ background: #8FFFAB;
}
.openerp .oe_kanban_color_5 .oe_kanban_color_border {
- border-color: #79D9D9;
+ border-color: #79D991;
}
/* Custom color#6 */
.openerp .oe_kanban_color_6 .oe_kanban_color_bglight {
- background: #C7D5FF;
+ background: #C7FFFF;
}
.openerp .oe_kanban_color_6 .oe_kanban_color_bgdark {
- background: #8FABFF;
+ background: #8FFFFF;
}
.openerp .oe_kanban_color_6 .oe_kanban_color_border {
- border-color: #8FABFF;
+ border-color: #79D9D9;
}
/* Custom color#7 */
.openerp .oe_kanban_color_7 .oe_kanban_color_bglight {
- background: #E3C7FF;
+ background: #C7D5FF;
}
.openerp .oe_kanban_color_7 .oe_kanban_color_bgdark {
- background: #C78FFF;
+ background: #8FABFF;
}
.openerp .oe_kanban_color_7 .oe_kanban_color_border {
- border-color: #A979D9;
+ border-color: #8FABFF;
}
/* Custom color#8 */
.openerp .oe_kanban_color_8 .oe_kanban_color_bglight {
- background: #FFC7F1;
+ background: #E3C7FF;
}
.openerp .oe_kanban_color_8 .oe_kanban_color_bgdark {
- background: #FF8FE3;
+ background: #C78FFF;
}
.openerp .oe_kanban_color_8 .oe_kanban_color_border {
+ border-color: #A979D9;
+}
+
+/* Custom color#9 */
+.openerp .oe_kanban_color_9 .oe_kanban_color_bglight {
+ background: #FFC7F1;
+}
+.openerp .oe_kanban_color_9 .oe_kanban_color_bgdark {
+ background: #FF8FE3;
+}
+.openerp .oe_kanban_color_9 .oe_kanban_color_border {
border-color: #D979C1;
}
@@ -224,3 +282,8 @@
.openerp .oe_kanban_color_alert .oe_kanban_color_border {
border-color: #c00 !important;
}
+
+/* Green color */
+.openerp .oe_kanban_color_green .oe_kanban_color_border {
+ border-color: #0c0 !important;
+}
diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js
index 11d675a5705..c43ea503841 100644
--- a/addons/web_kanban/static/src/js/kanban.js
+++ b/addons/web_kanban/static/src/js/kanban.js
@@ -1,37 +1,58 @@
openerp.web_kanban = function (openerp) {
+var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
-QWeb.add_template('/web_kanban/static/src/xml/web_kanban.xml');
openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView');
+
openerp.web_kanban.KanbanView = openerp.web.View.extend({
+ template: "KanbanView",
+ default_nr_columns: 3,
init: function (parent, dataset, view_id, options) {
this._super(parent);
this.set_default_options(options);
this.dataset = dataset;
- this.model = dataset.model;
this.view_id = view_id;
this.fields_view = {};
- this.group_by = [];
- this.source_index = {};
- this.all_display_data = false;
+ this.fields_keys = [];
+ this.group_by = null;
+ this.state = {
+ groups : {},
+ records : {}
+ };
this.groups = [];
- this.qweb = new QWeb2.Engine();
- this.aggregates = {};
- this.NO_OF_COLUMNS = 3;
this.form_dialog = new openerp.web.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start();
- this.form_dialog.on_form_dialog_saved.add_last(this.on_record_saved);
+ this.form_dialog.on_form_dialog_saved.add_last(this.do_reload);
+ this.aggregates = {};
+ this.qweb = new QWeb2.Engine();
+ this.qweb.debug = openerp.connection.debug;
+ this.qweb.default_dict = {
+ '_' : _,
+ '_t' : _t
+ }
+ this.has_been_loaded = $.Deferred();
+ this.search_domain = this.search_context = this.search_group_by = null;
+ this.currently_dragging = {};
},
start: function() {
this._super();
- return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "kanban"}, this.on_loaded);
+ this.$element.find('button.oe_kanban_button_new').click(this.do_add_record);
+ this.$groups = this.$element.find('.oe_kanban_groups tr');
+ var context = new openerp.web.CompoundContext(this.dataset.get_context());
+ return this.rpc('/web/view/load', {
+ 'model': this.dataset.model,
+ 'view_id': this.view_id,
+ 'view_type': 'kanban',
+ context: context
+ }, this.on_loaded);
},
on_loaded: function(data) {
- var self = this;
this.fields_view = data;
+ this.fields_keys = _.keys(this.fields_view.fields);
this.add_qweb_template();
+ this.has_been_loaded.resolve();
},
add_qweb_template: function() {
- var group_operator = ["avg", "max", "min", "sum", "count"]
+ var group_operator = ['avg', 'max', 'min', 'sum', 'count']
for (var i=0, ii=this.fields_view.arch.children.length; i < ii; i++) {
var child = this.fields_view.arch.children[i];
if (child.tag === "field") {
@@ -49,28 +70,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
}
}
},
- kanban_color: function(variable) {
- var number_of_color_schemes = 8,
- index = 0;
- switch (typeof(variable)) {
- case 'string':
- for (var i=0, ii=variable.length; i<ii; i++) {
- index += variable.charCodeAt(i);
- }
- break;
- case 'number':
- index = Math.round(variable);
- break;
- default:
- return '';
- }
- return 'oe_kanban_color_' + ((index % number_of_color_schemes) || number_of_color_schemes);
- },
- kanban_gravatar: function(email, size) {
- size = size || 22;
- var email_md5 = '2eb60ad22dadcf4dc456b28390a80268';
- return 'http://www.gravatar.com/avatar/' + email_md5 + '.png?s=' + size;
- },
transform_qweb_template: function(node) {
var qweb_prefix = QWeb.prefix;
switch (node.tag) {
@@ -90,7 +89,7 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
});
if (node.attrs['data-states']) {
var states = _.map(node.attrs['data-states'].split(','), function(state) {
- return "record.state.value == '" + _.trim(state) + "'";
+ return "record.state.raw_value == '" + _.trim(state) + "'";
});
node.attrs['t-if'] = states.join(' or ');
}
@@ -122,359 +121,391 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
}
}
},
- on_show_data: function() {
- var self = this;
- if (!this.group_by.length) {
- this.do_record_group();
- }
- this.$element.html(QWeb.render("KanbanView", {"data": self.all_display_data}));
- this.on_reload_kanban();
- this.$element.find(".oe_vertical_text").hide();
- var drag_handel = false;
- if (this.$element.find(".oe_kanban_draghandle").length > 0) {
- drag_handel = ".oe_kanban_draghandle";
- }
- if (!this.group_by.length) {
- drag_handel = true;
- }
- this.$element.find(".oe_column").sortable({
- connectWith: ".oe_column",
- handle : drag_handel,
- start: function(event, ui) {
- self.source_index['index'] = ui.item.index();
- self.source_index['column'] = ui.item.parent().attr('id');
- },
- stop: self.on_receive_record,
- scroll: false
- });
- this.$element.find(".oe_column").disableSelection()
- this.$element.find('button.oe_kanban_button_new').click(this.do_add_record);
- this.$element.find(".fold-columns-icon").click(function(event) {
- self.do_fold_unfold_columns(event, this.id);
- });
- },
- do_fold_unfold_columns: function(event, element_id) {
- var column_id = "column_" + element_id;
- var column_element = this.$element.find("#" + column_id + " .oe_fold_column");
- if (column_element.is(":hidden")) {
- this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/minus-icon.png');
- column_element.show();
- this.$element.find("#" + column_id + ".oe_table_column").css("width",Math.round(99 / this.all_display_data.length) + "%");
- this.$element.find("#" + column_id + ".oe_vertical_text").hide();
- }
- else{
- this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/plus-icon.png');
- column_element.hide();
- this.$element.find("#" + column_id + ".oe_table_column").css("width","0.5%");
- this.$element.find("#" + column_id + ".oe_vertical_text").show();
- }
-
- },
- do_record_group: function() {
- if (this.NO_OF_COLUMNS && this.all_display_data.length > 0) {
- var records = this.all_display_data[0].records;
- var record_per_group = Math.round((records).length / this.NO_OF_COLUMNS);
- this.all_display_data = [];
- for (var i=0, ii=this.NO_OF_COLUMNS; i < ii; i++) {
- this.all_display_data.push({'records': records.slice(0,record_per_group), 'value':i, 'header' : false, 'ids':[]});
- records.splice(0,record_per_group);
- }
- }
- },
- on_button_click: function (button_attrs, record_id) {
- this.on_execute_button_click(this.dataset, button_attrs, record_id);
- },
do_add_record: function() {
this.dataset.index = null;
this.do_switch_view('form');
},
- do_edit_record: function(record_id) {
+ do_search: function(domain, context, group_by) {
var self = this;
- this.form_dialog.select_id(record_id).then(function() {
- self.form_dialog.open();
+ this.search_domain = domain;
+ this.search_context = context;
+ this.search_group_by = group_by;
+ $.when(this.has_been_loaded).then(function() {
+ self.group_by = group_by.length ? group_by[0] : self.fields_view.arch.attrs.default_group_by;
+ self.datagroup = new openerp.web.DataGroup(self, self.dataset.model, domain, context, self.group_by ? [self.group_by] : []);
+ self.datagroup.list(self.fields_keys, self.do_process_groups, self.do_process_dataset);
});
},
- on_record_saved: function(r) {
- var id = this.form_dialog.form.datarecord.id;
- this.on_reload_record(id);
- },
- do_change_color: function(record_id, $e) {
+ do_process_groups: function(groups) {
+ this.do_clear_groups();
+ this.dataset.ids = [];
var self = this,
- id = record_id,
- colors = '#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','),
- $cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 }));
- $e.after($cpicker);
- $cpicker.mouseenter(function() {
- clearTimeout($cpicker.data('timeoutId'));
- }).mouseleave(function(evt) {
- var timeoutId = setTimeout(function() { $cpicker.remove() }, 500);
- $cpicker.data('timeoutId', timeoutId);
- });
- $cpicker.find('a').click(function(evt) {
- var data = {};
- data[$e.data('name')] = $(this).data('color');
- self.dataset.write(id, data, {}, function() {
- self.on_reload_record(id);
+ remaining = groups.length - 1,
+ groups_array = [];
+ _.each(groups, function (group, index) {
+ var group_name = group.value,
+ group_value = group.value,
+ group_aggregates = {};
+ if (group.value instanceof Array) {
+ group_name = group.value[1];
+ group_value = group.value[0];
+ }
+ _.each(self.aggregates, function(value, key) {
+ group_aggregates[value] = group.aggregates[key];
+ });
+ var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
+ dataset.read_slice(self.fields_keys, {'domain': group.domain, 'context': group.context}, function(records) {
+ self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
+ groups_array[index] = new openerp.web_kanban.KanbanGroup(self, records, group_value, group_name, group_aggregates);
+ if (!remaining--) {
+ self.dataset.index = self.dataset.ids.length ? 0 : null;
+ self.do_add_groups(groups_array);
+ }
});
- $cpicker.remove();
- return false;
});
},
- /**
- Reload one record in view.
- record_id : reload record id.
- */
- on_reload_record: function (record_id){
+ do_process_dataset: function(dataset) {
var self = this;
- this.dataset.read_ids([record_id], _.keys(self.fields_view.fields), function (records) {
- if (records.length > 0) {
- for (var i=0, ii=self.all_display_data.length; i < ii; i++) {
- for(j=0, jj=self.all_display_data[i].records.length; j < jj; j++) {
- if (self.all_display_data[i].records[j].id == record_id) {
- _.extend(self.all_display_data[i].records[j], records[0]);
- self.$element.find("#main_" + record_id).children().remove();
- self.$element.find("#main_" + record_id).append(self.qweb.render('kanban-box', {
- record: self.do_transform_record(self.all_display_data[i].records[j]),
- kanban_color: self.kanban_color,
- kanban_gravatar: self.kanban_gravatar
- }));
- break;
- }
+ this.do_clear_groups();
+ this.dataset.read_slice(this.fields_keys, {}, function(records) {
+ var groups = [];
+ while (records.length) {
+ for (var i = 0; i < self.default_nr_columns; i++) {
+ if (!groups[i]) {
+ groups[i] = [];
}
+ groups[i].push(records.shift());
}
- self.$element.find("#main_" + record_id + " .oe_kanban_action").click(self.on_action_clicked);
- self.$element.find("#main_" + record_id + " .oe_kanban_box_show_onclick_trigger").click(function() {
- $(this).parent("#main_" + record_id + " .oe_kanban_box").find(".oe_kanban_box_show_onclick").toggle();
- });
}
+ for (var i = 0; i < groups.length; i++) {
+ groups[i] = new openerp.web_kanban.KanbanGroup(self, _.compact(groups[i]));
+ }
+ self.do_add_groups(groups);
});
-
},
- do_delete: function (id) {
- var self = this;
- return $.when(this.dataset.unlink([id])).then(function () {
- self.drop_records(id);
- });
+ do_reload: function() {
+ this.do_search(this.search_domain, this.search_context, this.search_group_by);
},
- drop_records: function (id) {
- var self = this;
- _.each(self.all_display_data, function(data, index) {
- _.each(data.records, function(record, index_row) {
- if (parseInt(record.id) == id) {
- self.all_display_data[index]['records'].splice(index_row, 1);
- self.all_display_data[index]['ids'].splice(index_row, 1);
- return false;
- }
- });
+ do_clear_groups: function() {
+ _.each(this.groups, function(group) {
+ group.stop();
});
- self.$element.find("#main_" + id).remove();
+ this.groups = [];
+ this.$element.find('.oe_kanban_groups_headers, .oe_kanban_groups_records').empty();
},
- on_execute_button_click: function (dataset, button_attrs, record_id) {
+ do_add_groups: function(groups) {
var self = this;
- this.do_execute_action(
- button_attrs, dataset,
- record_id, function () {
- self.on_reload_record(record_id);
- }
- );
+ _.each(groups, function(group) {
+ self.groups[group.undefined_title ? 'unshift' : 'push'](group);
+ });
+ _.each(this.groups, function(group) {
+ group.appendTo(self.$element.find('.oe_kanban_groups_headers'));
+ });
+ this.on_groups_started();
},
- on_receive_record: function (event, ui) {
+ on_groups_started: function() {
var self = this;
- var from = ui.item.index();
- var search_action = false;
- var to = ui.item.prev().index() || 0;
- if (!ui.item.attr("id")) {
- return false;
+ this.compute_groups_width();
+ if (this.group_by) {
+ this.$element.find('.oe_kanban_column').sortable({
+ connectWith: '.oe_kanban_column',
+ handle : '.oe_kanban_draghandle',
+ start: function(event, ui) {
+ self.currently_dragging.index = ui.item.index();
+ self.currently_dragging.group = ui.item.parents('.oe_kanban_column:first').data('widget');
+ },
+ stop: function(event, ui) {
+ var record = ui.item.data('widget'),
+ old_index = self.currently_dragging.index,
+ new_index = ui.item.index(),
+ old_group = self.currently_dragging.group,
+ new_group = ui.item.parents('.oe_kanban_column:first').data('widget');
+ if (!(old_group.title === new_group.title && old_group.value === new_group.value && old_index == new_index)) {
+ self.on_record_moved(record, old_group, old_index, new_group, new_index);
+ }
+ },
+ scroll: false
+ });
+ } else {
+ this.$element.find('.oe_kanban_draghandle').removeClass('oe_kanban_draghandle');
}
- if (self.fields_view.fields.sequence != undefined && ((self.source_index.index >= 0 && self.source_index.index != from) ||
- (self.source_index.column && self.source_index.column != ui.item.parent().attr('id')))) {
- var child_record = ui.item.parent().children();
- var data, sequence = 1, index = to;
- child_record.splice(0, to);
- var flag = false;
- if (to >= 0 && child_record) {
- var record_id = parseInt($(child_record).attr("id").split("_")[1]);
- if (record_id) {
- _.each(self.all_display_data, function(data, index) {
- _.each(data.records, function(record, index_row) {
- if(record_id == record.id && record.sequence) {
- sequence = record.sequence;
- flag = true;
- return false;
- }
- });
- if(flag) {return false;}
- });
- }
- }
- _.each(child_record, function (child) {
- var child_id = parseInt($(child).attr("id").split("_")[1]);
- if (child_id) {
- flag = false;
- _.each(self.all_display_data, function(data, index) {
- _.each(data.records, function(record, index_row) {
- if(parseInt(record.id) == child_id) {
- self.all_display_data[index]['records'][index_row]['sequence'] = sequence;
- flag = true;
- return false;
- }
- });
- if (flag) {return false;}
- });
- self.dataset.write(child_id, {sequence: sequence});
- sequence++;
- search_action = true;
- }
+ },
+ on_record_moved : function(record, old_group, old_index, new_group, new_index) {
+ if (old_group === new_group) {
+ new_group.records.splice(old_index, 1);
+ new_group.records.splice(new_index, 0, record);
+ new_group.do_save_sequences();
+ } else {
+ old_group.records.splice(old_index, 1);
+ new_group.records.splice(new_index, 0, record);
+ record.group = new_group;
+ var data = {};
+ data[this.group_by] = new_group.value;
+ this.dataset.write(record.id, data, {}, function() {
+ record.do_reload();
+ new_group.do_save_sequences();
});
}
- if (self.group_by.length > 0 && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) {
- var value = ui.item.closest("td").attr("id");
- if (value) {
- var data_val = {};
- var wirte_id = parseInt(ui.item.attr("id").split("_")[1]);
- value = value.split("_")[1];
- if (value == 'false') {
- value = false;
- }
- var update_record = false;
- _.each(self.all_display_data, function(data, index) {
- _.each(data.records, function(record, index_row) {
- if(parseInt(record.id) == wirte_id) {
- self.all_display_data[index]['records'][index_row][self.group_by[0]] = value;
- update_record = self.all_display_data[index]['records'].splice(index_row,1)
- return false;
- }
- });
- if (update_record) {return false;}
- });
- _.each(self.all_display_data, function(data, index) {
- if (data.value == value || (data.value == 'false' && value == false)) {
- self.all_display_data[index]['records'].push(update_record[0]);
- }
- });
- data_val[self.group_by[0]] = value;
- self.dataset.write(wirte_id, data_val);
- search_action = true;
+ },
+ do_show: function () {
+ this.$element.show();
+ },
+ do_hide: function () {
+ this.$element.hide();
+ },
+ compute_groups_width: function() {
+ var unfolded = 0;
+ _.each(this.groups, function(group) {
+ unfolded += group.state.folded ? 0 : 1;
+ group.$element.css('width', '');
+ });
+ _.each(this.groups, function(group) {
+ if (!group.state.folded) {
+ group.$element.css('width', Math.round(100/unfolded) + '%');
}
+ });
+ }
+});
+
+openerp.web_kanban.KanbanGroup = openerp.web.Widget.extend({
+ template: 'KanbanView.group_header',
+ init: function (parent, records, value, title, aggregates) {
+ var self = this;
+ this._super(parent);
+ this.view = parent;
+ this.value = value;
+ this.title = title;
+ if (title === false) {
+ this.title = _t('Undefined');
+ this.undefined_title = true;
}
- if (search_action) {
- self.on_reload_kanban();
+ this.aggregates = aggregates || {};
+ var key = this.view.group_by + '-' + value;
+ if (!this.view.state.groups[key]) {
+ this.view.state.groups[key] = {
+ folded: false
+ }
}
- this.source_index = {};
+ this.state = this.view.state.groups[key];
+ this.$records = null;
+ this.records = _.map(records, function(record) {
+ return new openerp.web_kanban.KanbanRecord(self, record);
+ });
},
- on_reload_kanban: function (){
- var self = this;
- _.each(self.all_display_data, function(data, index) {
- if (data.records.length > 0){
- _.each(data.records, function(record) {
- self.$element.find("#main_" + record.id).children().remove();
- self.$element.find("#main_" + record.id).append(self.qweb.render('kanban-box', {
- record: self.do_transform_record(record),
- kanban_color: self.kanban_color,
- kanban_gravatar: self.kanban_gravatar
- }));
- });
- }
+ start: function() {
+ var self = this,
+ def = this._super();
+ this.$records = $(QWeb.render('KanbanView.group_records_container', { widget : this}));
+ this.$records.appendTo(this.view.$element.find('.oe_kanban_groups_records'));
+ _.each(this.records, function(record) {
+ record.appendTo(self.$records);
});
- this.$element.find('.oe_kanban_action').click(this.on_action_clicked);
- this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() {
- $(this).parent('.oe_kanban_box').find('.oe_kanban_box_show_onclick').toggle();
+ this.$element.find(".oe_kanban_fold_icon").click(function() {
+ self.do_toggle_fold();
+ self.view.compute_groups_width();
+ return false;
});
+ if (this.state.folded) {
+ this.do_toggle_fold();
+ }
+ this.$element.data('widget', this);
+ this.$records.data('widget', this);
+ return def;
},
- on_action_clicked: function(evt) {
- evt.preventDefault();
- var $action = $(evt.currentTarget),
- record_id = parseInt($action.closest(".oe_kanban_record").attr("id").split('_')[1]),
- type = $action.data('type');
- if (type == 'delete') {
- this.do_delete(record_id);
- } else if (type == 'edit') {
- this.do_edit_record(record_id);
- } else if (type == 'color') {
- this.do_change_color(record_id, $action);
- } else {
- var button_attrs = $action.data();
- this.on_button_click(button_attrs, record_id);
+ stop: function() {
+ this._super();
+ if (this.$records) {
+ this.$records.remove();
}
},
- do_transform_record: function(record) {
+ remove_record: function(id, remove_from_dataset) {
+ for (var i = 0, ii = this.records.length; i < ii; i++) {
+ if (this.records[i]['id'] === id) {
+ this.records.splice(i, 1);
+ }
+ }
+ },
+ do_toggle_fold: function(compute_width) {
+ this.$element.toggleClass('oe_kanban_group_folded');
+ this.$records.find('.oe_kanban_record').toggle();
+ this.state.folded = this.$element.is('.oe_kanban_group_folded');
+ },
+ do_save_sequences: function() {
+ var self = this;
+ if (_.indexOf(this.view.fields_keys, 'sequence') > -1) {
+ _.each(this.records, function(record, index) {
+ self.view.dataset.write(record.id, { sequence : index });
+ });
+ }
+ }
+});
+
+openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
+ template: 'KanbanView.record',
+ init: function (parent, record) {
+ this._super(parent);
+ this.group = parent;
+ this.view = parent.view;
+ this.id = null;
+ this.set_record(record);
+ if (!this.view.state.records[this.id]) {
+ this.view.state.records[this.id] = {
+ folded: false
+ };
+ }
+ this.state = this.view.state.records[this.id];
+ },
+ set_record: function(record) {
+ this.id = record.id;
+ this.record = this.transform_record(record);
+ },
+ start: function() {
+ this._super();
+ this.$element.data('widget', this);
+ this.bind_events();
+ },
+ transform_record: function(record) {
var self = this,
new_record = {};
_.each(record, function(value, name) {
- var r = _.clone(self.fields_view.fields[name]);
+ var r = _.clone(self.view.fields_view.fields[name]);
r.raw_value = value;
r.value = openerp.web.format_value(value, r);
new_record[name] = r;
});
return new_record;
},
- do_search: function (domain, context, group_by) {
- var self = this;
- self.group_by = group_by;
- var self = this,
- group_by = self.group_by;
- if (!group_by.length && this.fields_view.arch.attrs.default_group_by) {
- group_by = [this.fields_view.arch.attrs.default_group_by];
- self.group_by = group_by;
+ render: function() {
+ var ctx = {
+ record: this.record,
+ widget: this
}
- self.datagroup = new openerp.web.DataGroup(self, self.model, domain, context, group_by);
- self.datagroup.list(
- _.keys(self.fields_view.fields),
- function (groups) {
- self.groups = groups;
- if (groups.length) {
- self.do_render_group(groups);
- } else {
- self.all_display_data = [];
- self.on_show_data();
- }
- },
- function (dataset) {
- self.groups = [];
- self.dataset.read_slice(_.keys(self.fields_view.fields), {}, function(records) {
- if (records.length) {
- self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
- } else {
- self.all_display_data = [];
- }
- self.$element.find(".oe_kanban_view").remove();
- self.on_show_data();
- });
+ for (var p in this) {
+ if (_.startsWith(p, 'kanban_')) {
+ ctx[p] = _.bind(this[p], this);
}
- );
+ }
+ return this._super({
+ 'content': this.view.qweb.render('kanban-box', ctx)
+ });
},
- do_render_group : function (datagroups) {
- this.all_display_data = [];
- var self = this;
- _.each(datagroups, function (group) {
- var group_name = group.value;
- var group_value = group.value;
- if (!group.value) {
- group_name = "Undefined";
- group_value = 'false';
- } else if (group.value instanceof Array) {
- group_name = group.value[1];
- group_value = group.value[0];
+ bind_events: function() {
+ var self = this,
+ $show_on_click = self.$element.find('.oe_kanban_box_show_onclick');
+ $show_on_click.toggle(this.state.folded);
+ this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() {
+ $show_on_click.toggle();
+ self.state.folded = !self.state.folded;
+ });
+ this.$element.find('.oe_kanban_action').click(function() {
+ var $action = $(this),
+ type = $action.data('type') || 'button',
+ method = 'do_action_' + type;
+ if (typeof self[method] === 'function') {
+ self[method]($action);
+ } else {
+ self.do_warn("Kanban: no action for type : " + type);
}
- var group_aggregates = {};
- _.each(self.aggregates, function(value, key) {
- group_aggregates[value] = group.aggregates[key];
+ return false;
+ });
+ },
+ do_action_delete: function($action) {
+ var self = this;
+ if (confirm(_t("Are you sure you want to delete this record ?"))) {
+ return $.when(this.view.dataset.unlink([this.id])).then(function() {
+ self.group.remove_record(self.id)
+ self.stop();
});
- var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
- dataset.read_slice(_.keys(self.fields_view.fields), {'domain': group.domain, 'context': group.context}, function(records) {
- self.all_display_data.push({"value" : group_value, "records": records, 'header':group_name, 'ids': dataset.ids, 'aggregates': group_aggregates});
- if (datagroups.length == self.all_display_data.length) {
- self.$element.find(".oe_kanban_view").remove();
- self.on_show_data();
- }
+ }
+ },
+ do_action_edit: function($action) {
+ var self = this;
+ if ($action.attr('target') === 'dialog') {
+ this.view.form_dialog.select_id(this.id).then(function() {
+ self.view.form_dialog.open();
+ });
+ } else {
+ if (self.view.dataset.select_id(this.id)) {
+ this.view.do_switch_view('form');
+ } else {
+ this.do_warn("Kanban: could not find id#" + id);
+ }
+ }
+ },
+ do_action_color: function($action) {
+ var self = this,
+ colors = '#FFFFFF,#CCCCCC,#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','),
+ $cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 }));
+ $action.after($cpicker);
+ $cpicker.mouseenter(function() {
+ clearTimeout($cpicker.data('timeoutId'));
+ }).mouseleave(function(evt) {
+ var timeoutId = setTimeout(function() { $cpicker.remove() }, 500);
+ $cpicker.data('timeoutId', timeoutId);
+ });
+ $cpicker.find('a').click(function() {
+ var data = {};
+ data[$action.data('name')] = $(this).data('color');
+ self.view.dataset.write(self.id, data, {}, function() {
+ self.record[$action.data('name')] = $(this).data('color');
+ self.do_reload();
});
+ $cpicker.remove();
+ return false;
});
},
- do_show: function () {
- this.$element.show();
+ do_action_object: function ($action) {
+ var button_attrs = $action.data();
+ this.view.do_execute_action(button_attrs, this.view.dataset, this.id, this.do_reload);
},
- do_hide: function () {
- this.$element.hide();
+ do_reload: function() {
+ var self = this;
+ this.view.dataset.read_ids([this.id], this.view.fields_keys, function(records) {
+ if (records.length) {
+ self.set_record(records[0]);
+ self.do_render();
+ } else {
+ self.stop();
+ }
+ });
+ },
+ do_render: function() {
+ this.$element.html(this.render());
+ this.bind_events();
+ },
+ kanban_color: function(variable) {
+ var number_of_color_schemes = 10,
+ index = 0;
+ switch (typeof(variable)) {
+ case 'string':
+ for (var i=0, ii=variable.length; i<ii; i++) {
+ index += variable.charCodeAt(i);
+ }
+ break;
+ case 'number':
+ index = Math.round(variable);
+ break;
+ default:
+ return '';
+ }
+ var color = (index % number_of_color_schemes);
+ return 'oe_kanban_color_' + color;
+ },
+ kanban_gravatar: function(email, size) {
+ size = size || 22;
+ var email_md5 = $.md5(email);
+ return 'http://www.gravatar.com/avatar/' + email_md5 + '.png?s=' + size;
+ },
+ kanban_image: function(model, field, id) {
+ id = id || '';
+ return '/web/binary/image?session_id=' + this.session.session_id + '&model=' + model + '&field=' + field + '&id=' + id;
+ },
+ kanban_text_ellipsis: function(s, size) {
+ size = size || 160;
+ if (!s) {
+ return '';
+ }
+ return s.substr(0, size) + '...';
}
});
};
diff --git a/addons/web_kanban/static/src/xml/web_kanban.xml b/addons/web_kanban/static/src/xml/web_kanban.xml
index 8f3aaf457e9..c1346a0b90d 100644
--- a/addons/web_kanban/static/src/xml/web_kanban.xml
+++ b/addons/web_kanban/static/src/xml/web_kanban.xml
@@ -1,40 +1,50 @@
<template>
<t t-name="KanbanView">
- <table style="width:100%;" class="oe_kanban_view">
- <tr>
- <td>
- <div class="oe_form_header">
- <button type="button" class="oe_kanban_button_new">New</button>
- </div>
- </td>
- </tr>
- <tr>
- <td t-foreach="data" t-as="columns" class="oe_table_column" t-att-id="'column_' + columns.value">
- <img t-att-id="columns.value" class="fold-columns-icon" src="/web_kanban/static/src/img/minus-icon.png"/>
- <div class="oe_fold_column" t-att-id="'column_' + columns.value">
- <div class="oe_column_heading" t-if="columns.value and columns.header">
- <t t-esc="columns.header"/>
- </div>
- <div t-foreach="columns.aggregates or {}" t-as="aggregate">
- <i><u><t t-esc="aggregate"/>:</u> <t t-esc="aggregate_value"/></i>
+ <div class="oe_kanban_header">
+ <button type="button" class="oe_kanban_button_new">New</button>
+ </div>
+ <div class="oe_kanban_view">
+ <table style="width:100%;" class="oe_kanban_groups">
+ <tr class="oe_kanban_groups_headers">
+ </tr>
+ <tr class="oe_kanban_groups_records">
+ </tr>
+ </table>
+ </div>
+</t>
+<t t-name="KanbanView.group_header">
+ <td class="oe_kanban_group_header">
+ <t t-if="widget.view.group_by">
+ <div class="oe_kanban_fold_icon"></div>
+ <div class="oe_fold_column">
+ <div t-attf-class="oe_kanban_group_title #{widget.undefined_title ? 'oe_kanban_group_title_undefined' : ''}">
+ <t t-esc="widget.title"/>
</div>
+ <ul class="oe_kanban_aggregates">
+ <li t-foreach="widget.aggregates" t-as="aggregate">
+ <span><t t-esc="aggregate"/>:</span> <t t-esc="aggregate_value"/>
+ </li>
+ </ul>
</div>
- </td>
- </tr>
- <tr>
- <td t-foreach="data" t-as="columns" class="oe_column oe_table_column" t-att-id="'column_' + columns.value" t-attf-style="width: #{Math.round(99 / data.length)}%">
- <p t-if="columns.header" class="oe_vertical_text" t-att-id="'column_' + columns.value"><t t-esc="columns.header"/></p>
- <div t-foreach="columns.records" t-as="record" class="oe_fold_column oe_kanban_record" t-att-id="'main_' + record.id"/>
- </td>
- </tr>
- </table>
+ <p t-if="widget.title" class="oe_kanban_group_title_vertical"><t t-esc="widget.title"/></p>
+ </t>
+ </td>
+</t>
+<t t-name="KanbanView.group_records_container">
+ <td class="oe_kanban_column">
+ </td>
+</t>
+<t t-name="KanbanView.record">
+ <div class="oe_fold_column oe_kanban_record">
+ <t t-raw="content"/>
+ </div>
</t>
<t t-name="KanbanColorPicker">
<table cellspacing="0" cellpadding="0" border="0" class="oe_kanban_color_picker">
<tr>
<t t-foreach="colors" t-as="color">
<td t-att-bgcolor="color">
- <a href="#" t-att-data-color="color_index + 1"/>
+ <a href="#" t-att-data-color="color_index"/>
</td>
<t t-if="((color_index + 1) % Math.round(colors.length / columns)) == 0">&lt;/tr&gt;&lt;tr&gt;</t>
</t>
diff --git a/addons/web_mobile/po/ar.po b/addons/web_mobile/po/ar.po
new file mode 100644
index 00000000000..28e21aa44bf
--- /dev/null
+++ b/addons/web_mobile/po/ar.po
@@ -0,0 +1,66 @@
+# Arabic translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-03 15:13+0000\n"
+"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
+"Language-Team: Arabic <ar@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "OpenERP"
+msgstr "OpenERP"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Database:"
+msgstr "قاعدة البيانات:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Login:"
+msgstr "الدخول:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Password:"
+msgstr "كلمة المرور:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Login"
+msgstr "تسجيل الدخول"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Bad username or password"
+msgstr "اسم مستخدم او كلمة مرور خاطئة"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Favourite"
+msgstr "مفضّلة"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Preference"
+msgstr "التفضيلات"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Applications"
+msgstr "تطبيقات"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Options"
+msgstr "خيارات"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Logout"
+msgstr "تسجيل الخروج"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid ":"
+msgstr ":"
diff --git a/addons/web_mobile/po/da.po b/addons/web_mobile/po/da.po
index e0dbdc552d1..d61a3cba5b8 100644
--- a/addons/web_mobile/po/da.po
+++ b/addons/web_mobile/po/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-12 04:44+0000\n"
-"X-Generator: Launchpad (build 14124)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/de.po b/addons/web_mobile/po/de.po
index 701026b9331..ab74249a7ba 100644
--- a/addons/web_mobile/po/de.po
+++ b/addons/web_mobile/po/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/es.po b/addons/web_mobile/po/es.po
index 9a9e02c4893..0995630c08e 100644
--- a/addons/web_mobile/po/es.po
+++ b/addons/web_mobile/po/es.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-19 06:05+0000\n"
-"X-Generator: Launchpad (build 14157)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/es_EC.po b/addons/web_mobile/po/es_EC.po
index 5cff1023c4f..73dbcaea7e7 100644
--- a/addons/web_mobile/po/es_EC.po
+++ b/addons/web_mobile/po/es_EC.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/et.po b/addons/web_mobile/po/et.po
index 5b8d74c0c5b..c3e3994a9d9 100644
--- a/addons/web_mobile/po/et.po
+++ b/addons/web_mobile/po/et.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-11 05:42+0000\n"
-"X-Generator: Launchpad (build 14123)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/fr.po b/addons/web_mobile/po/fr.po
index b64bcecfb1e..aead113ca02 100644
--- a/addons/web_mobile/po/fr.po
+++ b/addons/web_mobile/po/fr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/gl.po b/addons/web_mobile/po/gl.po
index 4049dfb8d1f..482a3e05f58 100644
--- a/addons/web_mobile/po/gl.po
+++ b/addons/web_mobile/po/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/it.po b/addons/web_mobile/po/it.po
index 8d155374c0a..fdfce4385f5 100644
--- a/addons/web_mobile/po/it.po
+++ b/addons/web_mobile/po/it.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-09 05:22+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/nl_BE.po b/addons/web_mobile/po/nl_BE.po
index f483032890b..0a1171f1fe9 100644
--- a/addons/web_mobile/po/nl_BE.po
+++ b/addons/web_mobile/po/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-08 05:30+0000\n"
-"X-Generator: Launchpad (build 14110)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/pl.po b/addons/web_mobile/po/pl.po
new file mode 100644
index 00000000000..d5e04f22e00
--- /dev/null
+++ b/addons/web_mobile/po/pl.po
@@ -0,0 +1,66 @@
+# Polish translation for openerp-web
+# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
+# This file is distributed under the same license as the openerp-web package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openerp-web\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2011-10-07 10:39+0200\n"
+"PO-Revision-Date: 2011-11-04 16:26+0000\n"
+"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
+"X-Generator: Launchpad (build 14231)\n"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "OpenERP"
+msgstr ""
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Database:"
+msgstr "Baza danych:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Login:"
+msgstr "Login:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Password:"
+msgstr "Hasło:"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Login"
+msgstr "Login"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Bad username or password"
+msgstr "Niepoprawna nazwa użytkownika lub hasło"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Favourite"
+msgstr "Ulubione"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Preference"
+msgstr "Preferencje"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Applications"
+msgstr "Aplikacje"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Options"
+msgstr "Opcje"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid "Logout"
+msgstr "Wyloguj"
+
+#: addons/web_mobile/static/src/xml/web_mobile.xml:0
+msgid ":"
+msgstr ""
diff --git a/addons/web_mobile/po/sk.po b/addons/web_mobile/po/sk.po
index 5e10f135cf9..d550414317a 100644
--- a/addons/web_mobile/po/sk.po
+++ b/addons/web_mobile/po/sk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-24 05:18+0000\n"
-"X-Generator: Launchpad (build 14185)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/addons/web_mobile/po/sl.po b/addons/web_mobile/po/sl.po
index 041141d4824..8141108f9a9 100644
--- a/addons/web_mobile/po/sl.po
+++ b/addons/web_mobile/po/sl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2011-10-20 04:48+0000\n"
-"X-Generator: Launchpad (build 14165)\n"
+"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
+"X-Generator: Launchpad (build 14197)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
diff --git a/openerp-web.py b/openerp-web
index fe33585a233..a3b3d2fa1d5 100755
--- a/openerp-web.py
+++ b/openerp-web
@@ -1,34 +1,29 @@
#!/usr/bin/env python
+import json
+import logging
+import logging.config
import optparse
import os
import sys
-import json
import tempfile
-import logging
-import logging.config
import werkzeug.serving
import werkzeug.contrib.fixers
-path_root = os.path.dirname(os.path.abspath(__file__))
-path_addons = os.path.join(path_root, 'addons')
-if path_addons not in sys.path:
- sys.path.insert(0, path_addons)
-
optparser = optparse.OptionParser()
optparser.add_option("-s", "--session-path", dest="session_storage",
default=os.path.join(tempfile.gettempdir(), "oe-sessions"),
- help="directory used for session storage", metavar="DIR")
+ help="Directory used for session storage", metavar="DIR")
optparser.add_option("--server-host", dest="server_host",
default='127.0.0.1', help="OpenERP server hostname", metavar="HOST")
optparser.add_option("--server-port", dest="server_port", default=8069,
help="OpenERP server port", type="int", metavar="NUMBER")
optparser.add_option("--db-filter", dest="dbfilter", default='.*',
- help="Filter listed database", metavar="REGEXP")
-optparser.add_option('--addons-path', dest='addons_path', default=[path_addons], action='append',
- help="Path do addons directory", metavar="PATH")
+ help="Filter listed databases", metavar="REGEXP")
+optparser.add_option('--addons-path', dest='addons_path', default=[], action='append',
+ help="Path to addons directory", metavar="PATH")
optparser.add_option('--load', dest='server_wide_modules', default=['web'], action='append',
- help="Load a additional module before login (by default only 'web' is loaded)", metavar="MODULE")
+ help="Load an additional module before login (by default only 'web' is loaded)", metavar="MODULE")
server_options = optparse.OptionGroup(optparser, "Server configuration")
server_options.add_option("-p", "--port", dest="socket_port", default=8002,
@@ -55,19 +50,39 @@ logging_opts.add_option("--log-config", dest="log_config", default=os.path.join(
help="Logging configuration file", metavar="FILE")
optparser.add_option_group(logging_opts)
-import web.common.http
if __name__ == "__main__":
(options, args) = optparser.parse_args(sys.argv[1:])
- options.backend = 'xmlrpc'
+ if not options.addons_path:
+ path_root = os.path.dirname(os.path.abspath(__file__))
+ path_addons = os.path.join(path_root, 'addons')
+ if os.path.exists(path_addons):
+ options.addons_path.append(path_addons)
+
+ options.addons_path = [
+ path[:-1] if path[-1] in r'\/' else path
+ for path in options.addons_path
+ if os.path.exists(path)
+ ]
+
+ for path_addons in options.addons_path:
+ if path_addons not in sys.path:
+ sys.path.insert(0, path_addons)
+
+ try:
+ import web.common.http
+ except ImportError:
+ optparser.error('Error Importing base web module. Check correctness of --addons-path.')
+
+ options.backend = 'xmlrpc'
os.environ["TZ"] = "UTC"
- if sys.version_info >= (2, 7):
+ if sys.version_info >= (2, 7) and os.path.exists(options.log_config):
with open(options.log_config) as file:
dct = json.load(file)
logging.config.dictConfig(dct)
- logging.getLogger("").setLevel(getattr(logging, options.log_level.upper()))
+ logging.getLogger().setLevel(getattr(logging, options.log_level.upper()))
else:
logging.basicConfig(level=getattr(logging, options.log_level.upper()))
diff --git a/setup.py b/setup.py
index 374f7308ca8..3f108685f94 100755..100644
--- a/setup.py
+++ b/setup.py
@@ -1,113 +1,73 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-import glob, os, re, setuptools, sys
-from os.path import join, isfile
+import os
+import re
+import sys
+from setuptools import setup, find_packages
-# List all data files
-def data():
- files = []
- for root, dirnames, filenames in os.walk('openerp'):
- for filename in filenames:
- if not re.match(r'.*(\.pyc|\.pyo|\~)$',filename):
- files.append(os.path.join(root, filename))
- d = {}
- for v in files:
- k=os.path.dirname(v)
- if k in d:
- d[k].append(v)
- else:
- d[k]=[v]
- r = d.items()
- return r
+execfile('addons/web/common/release.py')
-def gen_manifest():
- file_list="\n".join(data())
- open('MANIFEST','w').write(file_list)
+version_dash_incompatible = False
+if 'bdist_rpm' in sys.argv:
+ version_dash_incompatible = True
+try:
+ import py2exe
+ from py2exe_utils import opts
+ version_dash_incompatible = True
+except ImportError:
+ opts = {}
+if version_dash_incompatible:
+ version = version.split('-')[0]
-def py2exe_options():
- if os.name == 'nt':
- import py2exe
- return {
- "console" : [ { "script": "openerp-server", "icon_resources": [(1, join("pixmaps","openerp-icon.ico"))], }],
- 'options' : {
- "py2exe": {
- "skip_archive": 1,
- "optimize": 2,
- "dist_dir": 'dist',
- "packages": [ "DAV", "HTMLParser", "PIL", "asynchat", "asyncore", "commands", "dateutil", "decimal", "email", "encodings", "imaplib", "lxml", "lxml._elementpath", "lxml.builder", "lxml.etree", "lxml.objectify", "mako", "openerp", "poplib", "pychart", "pydot", "pyparsing", "reportlab", "select", "simplejson", "smtplib", "uuid", "vatnumber" "vobject", "xml", "xml", "xml.dom", "xml.xpath", "yaml", ],
- "excludes" : ["Tkconstants","Tkinter","tcl"],
- }
- }
- }
- else:
- return {}
+FILE_PATTERNS = \
+ r'.+\.(py|cfg|po|pot|mo|txt|rst|gif|png|jpg|ico|mako|html|js|css|htc|swf)$'
+def find_data_files(source, patterns=FILE_PATTERNS):
+ file_matcher = re.compile(patterns, re.I)
+ out = []
+ for base, _, files in os.walk(source):
+ cur_files = []
+ for f in files:
+ if file_matcher.match(f):
+ cur_files.append(os.path.join(base, f))
+ if cur_files:
+ out.append(
+ (base, cur_files))
-execfile(join(os.path.dirname(__file__), 'openerp', 'release.py'))
+ return out
-setuptools.setup(
- name = 'openerp',
- version = version,
- description = description,
- long_description = long_desc,
- url = url,
- author = author,
- author_email = author_email,
- classifiers = filter(None, classifiers.split("\n")),
- license = license,
- scripts = ['openerp-server'],
- data_files = data(),
- packages = setuptools.find_packages(),
- #include_package_data = True,
- install_requires = [
- # TODO the pychart package we include in openerp corresponds to PyChart 1.37.
- # It seems there is a single difference, which is a spurious print in generate_docs.py.
- # It is probably safe to move to PyChart 1.39 (the latest one).
- # (Let setup.py choose the latest one, and we should check we can remove pychart from
- # our tree.) http://download.gna.org/pychart/
- # TODO 'pychart',
- 'babel',
- 'feedparser',
- 'gdata',
- 'lxml',
- 'mako',
- 'psycopg2',
- 'pydot',
- 'python-dateutil',
- 'python-ldap',
- 'python-openid',
- 'pytz',
- 'pywebdav',
- 'pyyaml',
- 'reportlab',
- 'simplejson',
- 'vatnumber',
- 'vobject',
- 'werkzeug',
- 'zsi',
- ],
- extras_require = {
- 'SSL' : ['pyopenssl'],
- },
- **py2exe_options()
+setup(
+ name=name,
+ version=version,
+ description=description,
+ long_description=long_description,
+ author=author,
+ author_email=author_email,
+ url=url,
+ download_url=download_url,
+ license=license,
+ install_requires=[
+ "Babel >= 0.9.6",
+ "simplejson >= 2.0.9",
+ "python-dateutil >= 1.4.1",
+ "pytz",
+ "werkzeug == 0.7",
+ ],
+ tests_require=[
+ 'unittest2',
+ 'mock',
+ ],
+ test_suite = 'unittest2.collector',
+ zip_safe=False,
+ packages=find_packages(),
+ classifiers=[
+ 'Development Status :: 6 - Production/Stable',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Environment :: Web Environment',
+ 'Topic :: Office/Business :: Financial',
+ ],
+ scripts=['openerp-web'],
+ data_files=(find_data_files('addons')
+ + opts.pop('data_files', [])
+ ),
+ **opts
)
-