From dc6db1450d0b37da46e837f7bf1becbf16726f4b Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Wed, 9 Jun 2021 08:27:53 +0000 Subject: [PATCH] [REM] web: old documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AFAIK, this documentation isn't built anywhere and is not maintained anyway. Since the developer documentation was recently removed from odoo/odoo repository, it's the right time to remove this old doc content. closes odoo/odoo#71898 Signed-off-by: Géry Debongnie (ged) --- addons/web/doc/Makefile | 154 ----- addons/web/doc/_static/openerp.png | Bin 3479 -> 0 bytes addons/web/doc/_templates/sidebarintro.html | 16 - addons/web/doc/_templates/sidebarlogo.html | 3 - addons/web/doc/_themes/LICENSE | 37 -- addons/web/doc/_themes/README | 31 - addons/web/doc/_themes/flask/layout.html | 25 - addons/web/doc/_themes/flask/relations.html | 19 - .../web/doc/_themes/flask/static/flasky.css_t | 396 ------------- .../doc/_themes/flask/static/small_flask.css | 70 --- addons/web/doc/_themes/flask/theme.conf | 9 - .../web/doc/_themes/flask_small/layout.html | 22 - .../_themes/flask_small/static/flasky.css_t | 287 --------- .../static/forkme_right_darkblue_121621.png | Bin 7791 -> 0 bytes addons/web/doc/_themes/flask_small/theme.conf | 10 - addons/web/doc/_themes/flask_theme_support.py | 86 --- addons/web/doc/addon-structure.txt | 12 - addons/web/doc/client_action.rst | 114 ---- addons/web/doc/conf.py | 260 -------- addons/web/doc/form_view.rst | 55 -- addons/web/doc/guidelines.rst | 194 ------ addons/web/doc/images/db-query.png | Bin 7142 -> 0 bytes addons/web/doc/images/runner.png | Bin 3963 -> 0 bytes addons/web/doc/images/runner2.png | Bin 6807 -> 0 bytes addons/web/doc/images/tests.png | Bin 65388 -> 0 bytes addons/web/doc/images/tests2.png | Bin 20114 -> 0 bytes addons/web/doc/images/tests3.png | Bin 20382 -> 0 bytes addons/web/doc/index.rst | 55 -- addons/web/doc/list_view.rst | 531 ----------------- addons/web/doc/make.bat | 170 ------ addons/web/doc/module.rst | 442 -------------- addons/web/doc/module/0 | 17 - addons/web/doc/module/10 | 13 - addons/web/doc/module/11 | 11 - addons/web/doc/module/12 | 28 - addons/web/doc/module/14 | 17 - addons/web/doc/module/15 | 19 - addons/web/doc/module/16 | 25 - addons/web/doc/module/17 | 52 -- addons/web/doc/module/18 | 19 - addons/web/doc/module/19 | 52 -- addons/web/doc/module/2 | 12 - addons/web/doc/module/20 | 64 -- addons/web/doc/module/21 | 27 - addons/web/doc/module/22 | 6 - addons/web/doc/module/23 | 14 - addons/web/doc/module/24 | 10 - addons/web/doc/module/25 | 55 -- addons/web/doc/module/26 | 38 -- addons/web/doc/module/27 | 28 - addons/web/doc/module/28 | 13 - addons/web/doc/module/29 | 37 -- addons/web/doc/module/3 | 9 - addons/web/doc/module/4 | 11 - addons/web/doc/module/5 | 11 - addons/web/doc/module/6 | 29 - addons/web/doc/module/8 | 14 - addons/web/doc/module/9 | 21 - addons/web/doc/module/series | 27 - addons/web/doc/module/testing_0.png | Bin 23285 -> 0 bytes addons/web/doc/module/testing_1.png | Bin 36183 -> 0 bytes addons/web/doc/search_view.rst | 560 ------------------ 62 files changed, 4237 deletions(-) delete mode 100644 addons/web/doc/Makefile delete mode 100644 addons/web/doc/_static/openerp.png delete mode 100644 addons/web/doc/_templates/sidebarintro.html delete mode 100644 addons/web/doc/_templates/sidebarlogo.html delete mode 100644 addons/web/doc/_themes/LICENSE delete mode 100644 addons/web/doc/_themes/README delete mode 100644 addons/web/doc/_themes/flask/layout.html delete mode 100644 addons/web/doc/_themes/flask/relations.html delete mode 100644 addons/web/doc/_themes/flask/static/flasky.css_t delete mode 100644 addons/web/doc/_themes/flask/static/small_flask.css delete mode 100644 addons/web/doc/_themes/flask/theme.conf delete mode 100644 addons/web/doc/_themes/flask_small/layout.html delete mode 100644 addons/web/doc/_themes/flask_small/static/flasky.css_t delete mode 100644 addons/web/doc/_themes/flask_small/static/forkme_right_darkblue_121621.png delete mode 100644 addons/web/doc/_themes/flask_small/theme.conf delete mode 100644 addons/web/doc/_themes/flask_theme_support.py delete mode 100644 addons/web/doc/addon-structure.txt delete mode 100644 addons/web/doc/client_action.rst delete mode 100644 addons/web/doc/conf.py delete mode 100644 addons/web/doc/form_view.rst delete mode 100644 addons/web/doc/guidelines.rst delete mode 100644 addons/web/doc/images/db-query.png delete mode 100644 addons/web/doc/images/runner.png delete mode 100644 addons/web/doc/images/runner2.png delete mode 100644 addons/web/doc/images/tests.png delete mode 100644 addons/web/doc/images/tests2.png delete mode 100644 addons/web/doc/images/tests3.png delete mode 100644 addons/web/doc/index.rst delete mode 100644 addons/web/doc/list_view.rst delete mode 100644 addons/web/doc/make.bat delete mode 100644 addons/web/doc/module.rst delete mode 100644 addons/web/doc/module/0 delete mode 100644 addons/web/doc/module/10 delete mode 100644 addons/web/doc/module/11 delete mode 100644 addons/web/doc/module/12 delete mode 100644 addons/web/doc/module/14 delete mode 100644 addons/web/doc/module/15 delete mode 100644 addons/web/doc/module/16 delete mode 100644 addons/web/doc/module/17 delete mode 100644 addons/web/doc/module/18 delete mode 100644 addons/web/doc/module/19 delete mode 100644 addons/web/doc/module/2 delete mode 100644 addons/web/doc/module/20 delete mode 100644 addons/web/doc/module/21 delete mode 100644 addons/web/doc/module/22 delete mode 100644 addons/web/doc/module/23 delete mode 100644 addons/web/doc/module/24 delete mode 100644 addons/web/doc/module/25 delete mode 100644 addons/web/doc/module/26 delete mode 100644 addons/web/doc/module/27 delete mode 100644 addons/web/doc/module/28 delete mode 100644 addons/web/doc/module/29 delete mode 100644 addons/web/doc/module/3 delete mode 100644 addons/web/doc/module/4 delete mode 100644 addons/web/doc/module/5 delete mode 100644 addons/web/doc/module/6 delete mode 100644 addons/web/doc/module/8 delete mode 100644 addons/web/doc/module/9 delete mode 100644 addons/web/doc/module/series delete mode 100644 addons/web/doc/module/testing_0.png delete mode 100644 addons/web/doc/module/testing_1.png delete mode 100644 addons/web/doc/search_view.rst diff --git a/addons/web/doc/Makefile b/addons/web/doc/Makefile deleted file mode 100644 index c1eff186583..00000000000 --- a/addons/web/doc/Makefile +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -q -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - sed -i '/-99999/d' _build/dirhtml/_static/flasky.css - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenERPTechnicalDocumentation.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenERPTechnicalDocumentation" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/addons/web/doc/_static/openerp.png b/addons/web/doc/_static/openerp.png deleted file mode 100644 index caa1b21d8d72e39b33028fa5ed85951e579fda32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3479 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 FV1nfOD~JF9 diff --git a/addons/web/doc/_templates/sidebarintro.html b/addons/web/doc/_templates/sidebarintro.html deleted file mode 100644 index bbe4c472607..00000000000 --- a/addons/web/doc/_templates/sidebarintro.html +++ /dev/null @@ -1,16 +0,0 @@ - - -

Other Docs

- - -

Useful Links

- diff --git a/addons/web/doc/_templates/sidebarlogo.html b/addons/web/doc/_templates/sidebarlogo.html deleted file mode 100644 index de6e3e5c851..00000000000 --- a/addons/web/doc/_templates/sidebarlogo.html +++ /dev/null @@ -1,3 +0,0 @@ - diff --git a/addons/web/doc/_themes/LICENSE b/addons/web/doc/_themes/LICENSE deleted file mode 100644 index 8daab7ee6ef..00000000000 --- a/addons/web/doc/_themes/LICENSE +++ /dev/null @@ -1,37 +0,0 @@ -Copyright (c) 2010 by Armin Ronacher. - -Some rights reserved. - -Redistribution and use in source and binary forms of the theme, with or -without modification, are permitted provided that the following conditions -are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - -* The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -We kindly ask you to only use these themes in an unmodified manner just -for Flask and Flask-related products, not for unrelated projects. If you -like the visual style and want to use it for your own projects, please -consider making some larger changes to the themes (such as changing -font faces, sizes, colors or margins). - -THIS THEME IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS THEME, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/addons/web/doc/_themes/README b/addons/web/doc/_themes/README deleted file mode 100644 index b3292bdff8e..00000000000 --- a/addons/web/doc/_themes/README +++ /dev/null @@ -1,31 +0,0 @@ -Flask Sphinx Styles -=================== - -This repository contains sphinx styles for Flask and Flask related -projects. To use this style in your Sphinx documentation, follow -this guide: - -1. put this folder as _themes into your docs folder. Alternatively - you can also use git submodules to check out the contents there. -2. add this to your conf.py: - - sys.path.append(os.path.abspath('_themes')) - html_theme_path = ['_themes'] - html_theme = 'flask' - -The following themes exist: - -- 'flask' - the standard flask documentation theme for large - projects -- 'flask_small' - small one-page theme. Intended to be used by - very small addon libraries for flask. - -The following options exist for the flask_small theme: - - [options] - index_logo = '' filename of a picture in _static - to be used as replacement for the - h1 in the index.rst file. - index_logo_height = 120px height of the index logo - github_fork = '' repository name on github for the - "fork me" badge diff --git a/addons/web/doc/_themes/flask/layout.html b/addons/web/doc/_themes/flask/layout.html deleted file mode 100644 index ad08eccd38d..00000000000 --- a/addons/web/doc/_themes/flask/layout.html +++ /dev/null @@ -1,25 +0,0 @@ -{%- extends "basic/layout.html" %} -{%- block extrahead %} - {{ super() }} - {% if theme_touch_icon %} - - {% endif %} - -{% endblock %} -{%- block relbar2 %}{% endblock %} -{% block header %} - {{ super() }} - {% if pagename == 'index' %} -
- {% endif %} -{% endblock %} -{%- block footer %} - - {% if pagename == 'index' %} -
- {% endif %} -{%- endblock %} diff --git a/addons/web/doc/_themes/flask/relations.html b/addons/web/doc/_themes/flask/relations.html deleted file mode 100644 index 3bbcde85bb4..00000000000 --- a/addons/web/doc/_themes/flask/relations.html +++ /dev/null @@ -1,19 +0,0 @@ -

Related Topics

- diff --git a/addons/web/doc/_themes/flask/static/flasky.css_t b/addons/web/doc/_themes/flask/static/flasky.css_t deleted file mode 100644 index 9fec3190fc9..00000000000 --- a/addons/web/doc/_themes/flask/static/flasky.css_t +++ /dev/null @@ -1,396 +0,0 @@ -/* - * flasky.css_t - * ~~~~~~~~~~~~ - * - * :copyright: Copyright 2010 by Armin Ronacher. - * :license: Flask Design License, see LICENSE for details. - */ - -{% set page_width = '80em' %} -{% set sidebar_width = '16em' %} - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: 'Georgia', serif; - font-size: 15px; - background-color: white; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - width: {{ page_width }}; - margin: 30px auto 0 auto; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 {{ sidebar_width }}; -} - -div.sphinxsidebar { - width: {{ sidebar_width }}; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 0px 0 0px; -} - -img.floatingflask { - padding: 0 0 10px 10px; - float: right; -} - -div.footer { - width: {{ page_width }}; - margin: 20px auto 30px auto; - font-size: 12px; - color: #888; - text-align: right; -} - -div.footer a { - color: #888; -} - -div.related { - display: none; -} - -div.sphinxsidebar a { - color: #444; - text-decoration: none; - border-bottom: 1px dotted #999; -} - -div.sphinxsidebar a:hover { - border-bottom: 1px solid #999; -} - -div.sphinxsidebar { - font-size: 12px; - line-height: 1.5; -} - -div.sphinxsidebarwrapper { - padding: 0px 10px; -} - -div.sphinxsidebarwrapper p.logo { - padding: 0 0 20px 0; - margin: 0; - text-align: center; -} - -div.sphinxsidebar h3, -div.sphinxsidebar h4 { - font-family: 'Garamond', 'Georgia', serif; - color: #444; - font-size: 22px; - font-weight: normal; - margin: 0 0 5px 0; - padding: 0; -} - -div.sphinxsidebar h4 { - font-size: 18px; -} - -div.sphinxsidebar h3 a { - color: #444; -} - -div.sphinxsidebar p.logo a, -div.sphinxsidebar h3 a, -div.sphinxsidebar p.logo a:hover, -div.sphinxsidebar h3 a:hover { - border: none; -} - -div.sphinxsidebar p { - color: #555; - margin: 10px 0; -} - -div.sphinxsidebar ul { - margin: 10px 0; - padding: 0; - color: #000; -} - -div.sphinxsidebar input { - border: 1px solid #ccc; - font-family: 'Georgia', serif; - font-size: 1em; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #004B6B; - text-decoration: underline; -} - -a:hover { - color: #6D4100; - text-decoration: underline; -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; -} - -{% if theme_index_logo %} -div.indexwrapper h1 { - /* We don't want it, I don't know why theme_index_logo is triggered. */ - /* text-indent: -999999px; */ - background: url({{ theme_index_logo }}) no-repeat center center; - height: {{ theme_index_logo_height }}; -} -{% endif %} - -div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; } -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #ddd; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #eaeaea; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - background: #fafafa; - margin: 20px -30px; - padding: 10px 30px; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; -} - -div.admonition tt.xref, div.admonition a tt { - border-bottom: 1px solid #fafafa; -} - -dd div.admonition { - margin-left: -60px; - padding-left: 60px; -} - -div.admonition p.admonition-title { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - font-size: 22px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight { - background-color: white; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt { - font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.9em; -} - -img.screenshot { -} - -tt.descname, tt.descclassname { - font-size: 0.95em; -} - -tt.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #eee; - background: #fdfdfd; - font-size: 0.9em; -} - -table.footnote + table.footnote { - margin-top: -15px; - border-top: none; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.footnote td.label { - width: 0px; - padding: 0.3em 0 0.3em 0.5em; -} - -table.footnote td { - padding: 0.3em 0.5em; -} - -dl { - margin: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -blockquote { - margin: 0 0 0 30px; - padding: 0; -} - -ul, ol { - margin: 10px 0 10px 30px; - padding: 0; -} - -pre { - background: #eee; - padding: 7px 30px; - margin: 15px -30px; - line-height: 1.3em; -} - -dl pre, blockquote pre, li pre { - margin-left: -60px; - padding-left: 60px; -} - -dl dl pre { - margin-left: -90px; - padding-left: 90px; -} - -tt { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, a tt { - background-color: #FBFBFB; - border-bottom: 1px solid white; -} - -a.reference { - text-decoration: none; - border-bottom: 1px dotted #004B6B; -} - -a.reference:hover { - border-bottom: 1px solid #6D4100; -} - -a.footnote-reference { - text-decoration: none; - font-size: 0.7em; - vertical-align: top; - border-bottom: 1px dotted #004B6B; -} - -a.footnote-reference:hover { - border-bottom: 1px solid #6D4100; -} - -a:hover tt { - background: #EEE; -} diff --git a/addons/web/doc/_themes/flask/static/small_flask.css b/addons/web/doc/_themes/flask/static/small_flask.css deleted file mode 100644 index 1c6df309edc..00000000000 --- a/addons/web/doc/_themes/flask/static/small_flask.css +++ /dev/null @@ -1,70 +0,0 @@ -/* - * small_flask.css_t - * ~~~~~~~~~~~~~~~~~ - * - * :copyright: Copyright 2010 by Armin Ronacher. - * :license: Flask Design License, see LICENSE for details. - */ - -body { - margin: 0; - padding: 20px 30px; -} - -div.documentwrapper { - float: none; - background: white; -} - -div.sphinxsidebar { - display: block; - float: none; - width: 102.5%; - margin: 50px -30px -20px -30px; - padding: 10px 20px; - background: #333; - color: white; -} - -div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p, -div.sphinxsidebar h3 a { - color: white; -} - -div.sphinxsidebar a { - color: #aaa; -} - -div.sphinxsidebar p.logo { - display: none; -} - -div.document { - width: 100%; - margin: 0; -} - -div.related { - display: block; - margin: 0; - padding: 10px 0 20px 0; -} - -div.related ul, -div.related ul li { - margin: 0; - padding: 0; -} - -div.footer { - display: none; -} - -div.bodywrapper { - margin: 0; -} - -div.body { - min-height: 0; - padding: 0; -} diff --git a/addons/web/doc/_themes/flask/theme.conf b/addons/web/doc/_themes/flask/theme.conf deleted file mode 100644 index 18c720f804c..00000000000 --- a/addons/web/doc/_themes/flask/theme.conf +++ /dev/null @@ -1,9 +0,0 @@ -[theme] -inherit = basic -stylesheet = flasky.css -pygments_style = flask_theme_support.FlaskyStyle - -[options] -index_logo = '' -index_logo_height = 120px -touch_icon = diff --git a/addons/web/doc/_themes/flask_small/layout.html b/addons/web/doc/_themes/flask_small/layout.html deleted file mode 100644 index afd7a912729..00000000000 --- a/addons/web/doc/_themes/flask_small/layout.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "basic/layout.html" %} -{% block header %} - {{ super() }} - {% if pagename == 'index' %} -
- {% endif %} -{% endblock %} -{% block footer %} - {% if pagename == 'index' %} -
- {% endif %} -{% endblock %} -{# do not display relbars #} -{% block relbar1 %}{% endblock %} -{% block relbar2 %} - {% if theme_github_fork %} - Fork me on GitHub - {% endif %} -{% endblock %} -{% block sidebar1 %}{% endblock %} -{% block sidebar2 %}{% endblock %} diff --git a/addons/web/doc/_themes/flask_small/static/flasky.css_t b/addons/web/doc/_themes/flask_small/static/flasky.css_t deleted file mode 100644 index fe2141c565e..00000000000 --- a/addons/web/doc/_themes/flask_small/static/flasky.css_t +++ /dev/null @@ -1,287 +0,0 @@ -/* - * flasky.css_t - * ~~~~~~~~~~~~ - * - * Sphinx stylesheet -- flasky theme based on nature theme. - * - * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: 'Georgia', serif; - font-size: 17px; - color: #000; - background: white; - margin: 0; - padding: 0; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 40px auto 0 auto; - width: 700px; -} - -hr { - border: 1px solid #B1B4B6; -} - -div.body { - background-color: #ffffff; - color: #3E4349; - padding: 0 30px 30px 30px; -} - -img.floatingflask { - padding: 0 0 10px 10px; - float: right; -} - -div.footer { - text-align: right; - color: #888; - padding: 10px; - font-size: 14px; - width: 650px; - margin: 0 auto 40px auto; -} - -div.footer a { - color: #888; - text-decoration: underline; -} - -div.related { - line-height: 32px; - color: #888; -} - -div.related ul { - padding: 0 0 0 10px; -} - -div.related a { - color: #444; -} - -/* -- body styles ----------------------------------------------------------- */ - -a { - color: #004B6B; - text-decoration: underline; -} - -a:hover { - color: #6D4100; - text-decoration: underline; -} - -div.body { - padding-bottom: 40px; /* saved for footer */ -} - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - margin: 30px 0px 10px 0px; - padding: 0; -} - -{% if theme_index_logo %} -div.indexwrapper h1 { - text-indent: -999999px; - background: url({{ theme_index_logo }}) no-repeat center center; - height: {{ theme_index_logo_height }}; -} -{% endif %} - -div.body h2 { font-size: 180%; } -div.body h3 { font-size: 150%; } -div.body h4 { font-size: 130%; } -div.body h5 { font-size: 100%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: white; - padding: 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - color: #444; - background: #eaeaea; -} - -div.body p, div.body dd, div.body li { - line-height: 1.4em; -} - -div.admonition { - background: #fafafa; - margin: 20px -30px; - padding: 10px 30px; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; -} - -div.admonition p.admonition-title { - font-family: 'Garamond', 'Georgia', serif; - font-weight: normal; - font-size: 24px; - margin: 0 0 10px 0; - padding: 0; - line-height: 1; -} - -div.admonition p.last { - margin-bottom: 0; -} - -div.highlight{ - background-color: white; -} - -dt:target, .highlight { - background: #FAF3E8; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre, tt { - font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; - font-size: 0.85em; -} - -img.screenshot { -} - -tt.descname, tt.descclassname { - font-size: 0.95em; -} - -tt.descname { - padding-right: 0.08em; -} - -img.screenshot { - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils { - border: 1px solid #888; - -moz-box-shadow: 2px 2px 4px #eee; - -webkit-box-shadow: 2px 2px 4px #eee; - box-shadow: 2px 2px 4px #eee; -} - -table.docutils td, table.docutils th { - border: 1px solid #888; - padding: 0.25em 0.7em; -} - -table.field-list, table.footnote { - border: none; - -moz-box-shadow: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -table.footnote { - margin: 15px 0; - width: 100%; - border: 1px solid #eee; -} - -table.field-list th { - padding: 0 0.8em 0 0; -} - -table.field-list td { - padding: 0; -} - -table.footnote td { - padding: 0.5em; -} - -dl { - margin: 0; - padding: 0; -} - -dl dd { - margin-left: 30px; -} - -pre { - padding: 0; - margin: 15px -30px; - padding: 8px; - line-height: 1.3em; - padding: 7px 30px; - background: #eee; - border-radius: 2px; - -moz-border-radius: 2px; - -webkit-border-radius: 2px; -} - -dl pre { - margin-left: -60px; - padding-left: 60px; -} - -tt { - background-color: #ecf0f3; - color: #222; - /* padding: 1px 2px; */ -} - -tt.xref, a tt { - background-color: #FBFBFB; -} - -a:hover tt { - background: #EEE; -} diff --git a/addons/web/doc/_themes/flask_small/static/forkme_right_darkblue_121621.png b/addons/web/doc/_themes/flask_small/static/forkme_right_darkblue_121621.png deleted file mode 100644 index 146ef8a800602169cf78c686fc5a6d138a76bc0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7791 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 - +-- __manifest__.py - +-- controllers/ - +-- static/ - +-- lib/ - +-- src/ - +-- css/ - +-- img/ - +-- js/ - +-- xml/ - +-- test/ - +-- test/ diff --git a/addons/web/doc/client_action.rst b/addons/web/doc/client_action.rst deleted file mode 100644 index 4852400df10..00000000000 --- a/addons/web/doc/client_action.rst +++ /dev/null @@ -1,114 +0,0 @@ -.. highlight:: javascript - -Client actions -============== - -Client actions are the client-side version of OpenERP's "Server -Actions": instead of allowing for semi-arbitrary code to be executed -in the server, they allow for execution of client-customized code. - -On the server side, a client action is an action of type -``ir.actions.client``, which has (at most) two properties: a mandatory -``tag``, which is an arbitrary string by which the client will -identify the action, and an optional ``params`` which is simply a map -of keys and values sent to the client as-is (this way, client actions -can be made generic and reused in multiple contexts). - -General Structure ------------------ - -In the OpenERP Web code, a client action only requires two pieces of -information: - -* Mapping the action's ``tag`` to an object - -* Providing said object. Two different types of objects can be mapped - to a client action: - - * An OpenERP Web widget, which must inherit from - :js:class:`openerp.web.Widget` - - * A regular javascript function - -The major difference is in the lifecycle of these: - -* if the client action maps to a function, the function will be called - when executing the action. The function can have no further - interaction with the Web Client itself, although it can return an - action which will be executed after it. - - The function takes 2 parameters: the ActionManager calling it and - the descriptor for the current action (the ``ir.actions.client`` - dictionary). - -* if, on the other hand, the client action maps to a - :js:class:`~openerp.web.Widget`, that - :js:class:`~openerp.web.Widget` will be instantiated and added to - the web client's canvas, with the usual - :js:class:`~openerp.web.Widget` lifecycle (essentially, it will - either take over the content area of the client or it will be - integrated within a dialog). - -For example, to create a client action displaying a ``res.widget`` -object:: - - // Registers the object 'openerp.web_dashboard.Widget' to the client - // action tag 'board.home.widgets' - instance.web.client_actions.add( - 'board.home.widgets', 'instance.web_dashboard.Widget'); - instance.web_dashboard.Widget = instance.web.Widget.extend({ - template: 'HomeWidget' - }); - -At this point, the generic :js:class:`~openerp.web.Widget` lifecycle -takes over, the template is rendered, inserted in the client DOM, -bound on the object's ``$el`` property and the object is started. - -The second parameter to the constructor is the descriptor for the -action itself, which contains any parameter provided:: - - init: function (parent, action) { - // execute the Widget's init - this._super(parent); - // board.home.widgets only takes a single param, the identifier of the - // res.widget object it should display. Store it for later - this.widget_id = action.params.widget_id; - } - -More complex initialization (DOM manipulations, RPC requests, ...) -should be performed in the :js:func:`~openerp.web.Widget.start()` -method. - -.. note:: - - As required by :js:class:`~openerp.web.Widget`'s contract, if - :js:func:`~openerp.web.Widget.start()` executes any asynchronous - code it should return a ``Promise`` so callers know when it's - ready for interaction. - -.. code-block:: javascript - - start: function () { - return Promise.all([ - this._super(), - // Simply read the res.widget object this action should display - new instance.web.Model('res.widget').call( - 'read', [[this.widget_id], ['title']]) - .then(this.proxy('on_widget_loaded') - ]); - } - -The client action can then behave exactly as it wishes to within its -root (``this.$el``). In this case, it performs further renderings once -its widget's content is retrieved:: - - on_widget_loaded: function (widgets) { - var widget = widgets[0]; - var url = _.sprintf( - '/web_dashboard/widgets/content?session_id=%s&widget_id=%d', - this.session.session_id, widget.id); - this.$el.html(QWeb.render('HomeWidget.content', { - widget: widget, - url: url - })); - } diff --git a/addons/web/doc/conf.py b/addons/web/doc/conf.py deleted file mode 100644 index 111018ad303..00000000000 --- a/addons/web/doc/conf.py +++ /dev/null @@ -1,260 +0,0 @@ -# -*- coding: utf-8 -*- -# -# OpenERP Technical Documentation configuration file, created by -# sphinx-quickstart on Fri Feb 17 16:14:06 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -sys.path.append(os.path.abspath('_themes')) -sys.path.insert(0, os.path.abspath('../addons')) -sys.path.insert(0, os.path.abspath('..')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', 'sphinx.ext.viewcode', - 'patchqueue' -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'OpenERP Web Developers Documentation' -copyright = u'2012, OpenERP s.a.' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '7.0' -# The full version, including alpha/beta/rc tags. -release = '7.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'flask' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['_themes'] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -html_sidebars = { - 'index': ['sidebarintro.html', 'sourcelink.html', 'searchbox.html'], - '**': ['sidebarlogo.html', 'localtoc.html', 'relations.html', - 'sourcelink.html', 'searchbox.html'] -} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'openerp-web-doc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'openerp-web-doc.tex', u'OpenERP Web Developers Documentation', - u'OpenERP s.a.', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'openerp-web-doc', u'OpenERP Web Developers Documentation', - [u'OpenERP s.a.'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'OpenERPWebDocumentation', u'OpenERP Web Developers Documentation', - u'OpenERP s.a.', 'OpenERPWebDocumentation', 'Developers documentation for the openerp-web project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -todo_include_todos = True - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - 'python': ('http://docs.python.org/', None), - 'openerpserver': ('http://doc.openerp.com/trunk/developers/server', None), -} diff --git a/addons/web/doc/form_view.rst b/addons/web/doc/form_view.rst deleted file mode 100644 index 98d4a4de67e..00000000000 --- a/addons/web/doc/form_view.rst +++ /dev/null @@ -1,55 +0,0 @@ -Notes on the usage of the Form View as a sub-widget -=================================================== - -Undocumented stuff ------------------- - -* ``initial_mode`` *option* defines the starting mode of the form - view, one of ``view`` and ``edit`` (?). Default value is ``view`` - (non-editable form). - -* ``embedded_view`` *attribute* has to be set separately when - providing a view directly, no option available for that usage. - - * View arch **must** contain node with - ``@class="oe_form_container"``, otherwise everything will break - without any info - - * Root element of view arch not being ``form`` may or may not work - correctly, no idea. - - * Freeform views => ``@version="7.0"`` - -* Form is not entirely loaded (some widgets may not appear) unless - ``on_record_loaded`` is called (or ``do_show``, which itself calls - ``on_record_loaded``). - -* "Empty" form => ``on_button_new`` (...), or manually call - ``default_get`` + ``on_record_loaded`` - -* Form fields default to width: 100%, padding, !important margin, can - be reached via ``.oe_form_field`` - -* Form *will* render buttons and a pager, offers options to locate - both outside of form itself (``$buttons`` and ``$pager``), providing - empty jquery objects (``$()``) seems to stop displaying both but not - sure if there are deleterious side-effects. - - Other options: - - * Pass in ``$(document.createDocumentFragment)`` to ensure it's a - DOM-compatible tree completely outside of the actual DOM. - - * ??? - -* readonly fields probably don't have a background, beware if need of - overlay - - * What is the difference between ``readonly`` and - ``effective_readonly``? - -* No facilities for DOM events handling/delegations e.g. handling - keyup/keydown/keypress from a form fields into the form's user. - - * Also no way to reverse from a DOM node (e.g. DOMEvent#target) back to a - form view field easily diff --git a/addons/web/doc/guidelines.rst b/addons/web/doc/guidelines.rst deleted file mode 100644 index 8721d372f5b..00000000000 --- a/addons/web/doc/guidelines.rst +++ /dev/null @@ -1,194 +0,0 @@ -Guidelines and Recommendations -============================== - -Web Module Recommendations --------------------------- - -Identifiers (``id`` attribute) should be avoided -'''''''''''''''''''''''''''''''''''''''''''''''' - -In generic applications and modules, ``@id`` limits the reusabily of -components and tends to make code more brittle. - -Just about all the time, they can be replaced with nothing, with -classes or with keeping a reference to a DOM node or a jQuery element -around. - -.. note:: - - If it is *absolutely necessary* to have an ``@id`` (because a - third-party library requires one and can't take a DOM element), it - should be generated with `_.uniqueId - `_ or some other similar - method. - -Avoid predictable/common CSS class names -'''''''''''''''''''''''''''''''''''''''' - -Class names such as "content" or "navigation" might match the desired -meaning/semantics, but it is likely an other developer will have the -same need, creating a naming conflict and unintended behavior. Generic -class names should be prefixed with e.g. the name of the component -they belong to (creating "informal" namespaces, much as in C or -Objective-C) - -Global selectors should be avoided -'''''''''''''''''''''''''''''''''' - -Because a component may be used several times in a single page (an -example in OpenERP is dashboards), queries should be restricted to a -given component's scope. Unfiltered selections such as ``$(selector)`` -or ``document.querySelectorAll(selector)`` will generally lead to -unintended or incorrect behavior. - -OpenERP Web's :js:class:`~openerp.web.Widget` has an attribute -providing its DOM root :js:attr:`Widget.$el `, -and a shortcut to select nodes directly :js:attr:`Widget.$ -`. - -More generally, never assume your components own or controls anything -beyond its own personal DOM. - -Understand deferreds -'''''''''''''''''''' - -Deferreds, promises, futures, … - -Known under many names, these objects are essential to and (in OpenERP -Web) widely used for making :doc:`asynchronous javascript operations -` palatable and understandable. - -OpenERP Web guidelines ----------------------- - -* HTML templating/rendering should use :doc:`qweb` unless absolutely - trivial. - -* All interactive components (components displaying information to the - screen or intercepting DOM events) must inherit from - :class:`~openerp.web.Widget` and correctly implement and use its API - and lifecycle. - -* All css classes must be prefixed with *oe_* . - -* Asynchronous functions (functions which call :ref:`session.rpc - ` directly or indirectly at the very least) *must* return - deferreds, so that callers of overriders can correctly synchronize - with them. - -New Javascript guidelines -------------------------- - -From v11, we introduce a new coding standard for Odoo Javascript code. Here it -is: - -* add "use strict"; on top of every odoo JS module - -* name all entities exported by a JS module. So, instead of - - .. code-block:: javascript - - return Widget.extend({ - ... - }); - -you should use: - - .. code-block:: javascript - - var MyWidget = Widget.extend({ - ... - }); - - return MyWidget - -* there should be one space between function and the left parenthesis: - - .. code-block:: javascript - - function (a, b) {} - -* JS files should have a (soft) limit of 80 chars width, and a hard limit of 100 - -* document every functions and every files, with the style JSDoc. - -* for function overriding other functions, consider adding the tag @override in - the JS Doc. Also, you can mention which method is overridden: - - .. code-block:: javascript - - /** - * When a save operation has been confirmed from the model, this method is - * called. - * - * @override method from field manager mixin - * @param {string} id - * @returns {Deferred} - */ - _confirmSave: function (id) { - -* there should be an empty line between the main function comments and the tags, - or parameter descriptions - -* avoid introspection: don't build dynamically a method name and call it. It is - more fragile and more difficult to refactor - -* methods should be private if possible - -* never read an attribute of an attribute on somethig that you have a reference. - So, this is not good: - - .. code-block:: javascript - - this.myObject.propA.propB - -* never use a reference to the parent widget - -* avoid using the 'include' functionality: extending a class is fine and does - not cause issue, including a class is much more fragile, and may not work. - -* For the widgets, here is how the various attributes/functions should be - ordered: - - 1. all static attributes, such as template, events, custom_events, ... - - 2. all methods from the lifecycle of a widget, in this order: init, willStart, - start, destroy - - 3. If there are public methods, a section titled "Public", with an empty line - before and after - - 4. all public methods, camelcased, in alphabetic order - - 5. If there are private methods, a section titled "Private", with an empty line - before and after - - 6. all private methods, camelcased and prefixed with _, in alphabetic order - - 7. If there are event handlers, a section titled "Handlers", with an empty line - before and after - - 8. all handlers, camelcased and prefixed with _on, in alphabetic order - - 9. If there are static methods, they should be in a section titled "Static". - All static methods are considered public, camelcased with no _. - -* write unit tests - -* for the event handlers defined by the key 'event' or 'custom_events', don't - inline the function. Always add a string name, and add the definition in the - handler section - -* one space after if and for - -* never call private methods on another object - -* object definition on more than one line: each element should have a trailing - comma. - -* strings: double quotes for all textual strings (such as "Hello"), and single - quotes for all other strings, such as a css selector '.o_form_view' - -* always use this._super.apply(this, arguments); - -* keys in an object: ordered by alphabetic order \ No newline at end of file diff --git a/addons/web/doc/images/db-query.png b/addons/web/doc/images/db-query.png deleted file mode 100644 index e063b724001871f3846ead587810069347a8eab6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7142 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 U?IK$f`NBkzl~#}{kudW8FIjHf#{d8T diff --git a/addons/web/doc/images/runner.png b/addons/web/doc/images/runner.png deleted file mode 100644 index bd48e9d29221767295afe05d2722ff332c93ab00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3963 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 C-5}fm diff --git a/addons/web/doc/images/tests.png b/addons/web/doc/images/tests.png deleted file mode 100644 index 84083d9e5ed7583da33261259fb1f4e84d46a650..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65388 zcmbrmbyOv>5;q6~12YWn4uiX2+}+&=cP{P@gS)%CySux)ySuwD^WOXR?4Gm#ZO*x= zq|)6325D*wKQ9*eSkZ%)TKinVRzBoixxQZYkpNwLHe2UI1 zXDfVWJI>ex*Dhcik1%^Ed+d8aN19x;!BAH+-6(7#d>UfeZ=uKrWHl&Ms#ReE--WVs zeD!2ysbDqzI&w6n>awMPamwl>n}L(rOkT53NY6Y2o==hR{6Bv0>0|@{QNI$tuMEBf z;w$6-q2&9IrwH?}K^E|@fxigzUxQ1f((a+b$MLDQmwQ-19}g%9$U}WO5Iw(Cb_)_5 z1Vn46H{lf{yGsTV1O&STNY%;m^SdWI2*{SKlJDo_mtc@(nAu&C5FjA3fUlYo*uO#% zCJ4yilCMksD}X4%fPnDM|F7`ZNfD4&L^hb{*VXyOk_Bi*=HaTSrysBHZN7#Jd2v#u zW9+=54^BTzxzU+FG@#e7qL{vpNI%x750e$+Oln-NAy59w%s-^1iut5RuZLtYUEV!9 zd~Pk<4UO;7CP7k3wW?gALo#`tzewYA-`TPyXG++{`^X!`WKIpcA?=eJN0*Y;-Jy@l%ISNYAz_v`Ag$Wl(DlO^);c_6jBJ9P`LDpNXYjqhCl$;jdI(8p|S z{Ju5wq}j7?3U}kkpan~A5xv80+`I(9z^McI#K zDiii=34ji=uj9>;9Go-Pff1XaHvFliLwm9>E?HTnx!@Icx;EMlgZDchTHzp>hRoLeQ1^v>%46Xp7;e|fbBlKj?`o|j*ANErB1g`GYb%qptQLx+Q-nN}K09E; zRgPn2Oc`!AtxC=oVA0IXtz2-P+z8VpmQO_vb4DM*P*!RrT)BiHF=shw86WXXen_2=s?l4$QY$EeDA;&Be-tZIb zqY^7!W~u|N1VM^XLlU`mcjZ%$Gp0>H3sh&5pL-FI(CX7KXP&B8f9iZp-M1^;q!dYs z?tPbzGc7Ug<~YyJhwvha7|kO@Gu0V*@qoz~otS{+xc(gr<+Qcjc?$vp&sHpl5yLT) z3I2yj*=dnn{no^g_@WL43A}oJrbnEv#dgDPx7%IeXtbrC0*TGg=#qE}9&f4Omk`b2 zxMSsW&ILU-t1;67-Fe2?n(VKcg?C=Xlg;BIA4wEkgAC{u-)zn>Ov6)fV2zPi-dJob zlWY$2n5~b@ihyYNdfxp7U06z-C~ST#2=82;aNAgfkbN|s#s#g@ zKH?1VAO5319gQNk%JA;_k~v11v{i*JWfs>VBO`+TPaS_%j}Q1ikG-$yTgBw_cobV- zi=Un?K4w^Wo)-o`yhUBA@+_d)YpVAZhwCE|spMkOmRZh!=M9h=6R0am1kh6%Jj@Un z%nFfTD0s(Q;W$6ga)N*eI;!|?@`ofOKO(vSmMS_jcVoD`1Uh-niuBP|+%5g93(N5$ zfZWHWJda7fS)#jA)JnijgB->3b#ndn|DcyF8tt~Law^Gt;szzzU1>|vx9ZdOX-S`VC2fB`#D}`eozqnomR}Z z%AV>rJ@rv&v2ecjBNPp6dKE}97(8Y3?}pdhqq={gkSoZVEz#$?XL0bjlSj`{r{fto z?1N+4L_Nf!^yA*mq6FVDuV-+zfN25hw!!!%Ge}=IKZ+=oKUnLwD+>w8XX1Xk(T`C7Dq_VdQ<$o-OKfK(sjVZa5iQ zg&(@Jn2BC3n3G25Uz&$f5%J~T>H-rm-;$fSSyB`B+zgABg(wRi_6Py2V3Qx|kRX45 zG+edJD;r#K3fZdA@Kp#8GRfZ4WI429D&eh~HnYvVuFxeufyoP$waeFDeLZ@XoN87M zsWsE9)$*$KV!%||D#FcdzWc%nm9ZoGkm;!$u+UXseX-fL559WlkfjJ zBV#6+q%4?c$VRx0Aa8($!Ye}7OW|0cAykH%j*t^86hSCZwPXMD23pKV1264PSAjX( zJef~wPaM*E1(3~oGKKpM;AV;SI#F1dJU^;dx(Rg_gNbH=Z_NL4?@X0{D9>Eg81M`y z*6ZYk7Sl(E)$OsX7Pq>Of?v(fZz&zLtDK}%F-|T}9a>a`2pa_z^B|6yDJHMYTSidL z3+I?s|Mfrv_%`8}ti@t~YN)bOKK_$S>Rn#VyAGub&-vln#EM}I_*Ul99}TbL*PWJTkDvqac_!|G{uY0Nf7Ym+Ug(^F}sapT2jl-jr3*< zW<1?7tfKP1NJf9*v@@a^j08c-g^= zT&Z6aF7uj=`QQ?B6TcX!4MxTrztf((7jKi*{$_74R{qP$iaWp#jM zGlGENkI4H55#N{=yDCImQOs+|Ar9#u+4Y-nYnGV@AQOe~IDk^Q)g%ex`NIe2&?V1& zh!_zVEPp2WD56&0lGaIwI7CGLDum2QhF-n{Z4 zmfw}hq`nX#2tL3QGBH13#nn_hdmHgzbMY6{`@hM5&)^0AhxI=q{{;&{K%)Mk!T&@4 z&i$v7H;`B>^PfIEbLXC(9%=t^|9&oUv@X=OP(^rwbcSgE&cuIgMlbSfhR+ivwYIdi zbZ-;=MyxOXlPIqMi56N2lJe&g$!}3ykAWcYV97I++=n2m`#Q)MVdIr#hSM~Q*2oML zb76N(_D{UjnX}qQt<$pFCA0IyIwaIQOtSwbQGo1!Qxq`ke+hq{m+wER8MHXyKN8Z> zi~a+-Ab%DABhP;;AW{DnwfGAIe+l>B3jRO53j!klAIb3NlcGjPN9X6~{r&xU*s{c3 z1z`+MH`ItwtuP#4n%m<^(WKgA)|Mr(2$^QLP1?-Xn4J6Xv_x12y6ux=x{1p}6`egM zN}Jv#>>l-7=QH^1X?LQ18F#(%|A+Sd!s7gRwh)io{izVFL^5AKTUNBe zvhYn@77KPox8LEjZi9kqLmpK-%rA|9ig0C<%(?#r>qN4}BFy`kLC6sD7%0VcP-cK+>qWNr@pV6`r_AWXDUzYf#*Uuy&AqCD5aEV-%7#{2TfA3DgqS&}4VlLb(+7JEcy3s&7AX3|}<#RjIt3XKw=0EMNsx_vgUicU5B7#?$ z@z-DX=PA2*AQX)@Au-XdePgxJYSYX4vwPt6@p7}n<@RP@0?0dVP?9}%nTcCaOD@N- ztl1C6>}zo@JR{ILK4{D?ls*%IvM8{!Ux5)-bJ#LXi=#l6BE}*jfbivp#H3j696vhh ze_Wudj3p$_)oFA83;|K*Vpj08t*m?;ky}aLlw>orSH><>9ZjG!g^A&aC5x{&3dHIr zXE(jvQPj8fMQRRO#oB)C^`G_$?oF^XS-|S2VOME$OQRrXIvL0^yvw<@K+AT-L`9bW2j(bodhj>ZrkrH}vJd}o zmcD7Jk+7Cit&oXQwYCs5ZDjz3#-Mg`Q_susS$~<2LKq0y&=P?20Y-nxP33dm@9O_$ zU3i%1o18ASa;J|RTbXb=>-cya*>S!MMNzVc8(ULz6-DTzSw1EK$R1*C#(mRu{7pA! zzpvyRHAOj6!pBF7*>e*oqIW<-k5OA1E%S|te@zpl3gyLAU8*Toee8GFxQ?O|2)XgJ zgG@G{=WZVgTfaJCqV%^~A|EnqLRKLs3(cm&fjx*xA>+2_yLnQ4KB)`p&&7vK`p^yXT187T6r5g!Tg=DF)<#S8zIN$Eb;|T_5zJSWtuV^?#Hl{4cHrm-mTDFm)<(t)1*@0|f7@9R5iwgRo=b56 z_ITpA54W{Sfp3Q1Lw#9TPxF%M`g)<(L3`!*lljs`<|C1kIi~Y&Uq}HYo4*V0jxP&> zR0=TFf067Ze#7}EBrQ$E3x($g!X=TP`JWA9c=mf}aD-Y;sCfg0f67)aYpfzCF8@Jp z9ofkDA2S?OQ`qW5!RQy>5lknsvDuEm@kXLkwrz@&%3IQMKmRZ{to)4=#ym)7&HoU3j&S3jD!m_VGj4BEN+ zr3>Yz=o%ZsF(fOMar&UM4P`iWlo~|$m(k! zCd$gFJIA2~`raL?u>vHfP#>q-Cf*$ir@^;3ZF>DBddzC(p}|cl%c+H0q!B3s(i+}! zVPXIVJ;Xy{>yV1&7HgUCVVI5fC5FUWN3-De_xmOX&@1ab%Bqw@lTv{OCUMB_tLx?} zmw6_C&KW(0@aT&b^7=wW-&Um&N=Z#0T(^>L*r#=FI#FPuj`d;xp`<~8UfbqMqyBl; zH4Tx~`UrJYeYw4P!g{VAk1S2kf96=i`TLi9>>3vb;PQA%QgXHsi#XkMx<3lbc)k$J(OTC-Z(dDFw?Xd4SO^cg30 zPpf}@L4+-m0!%nO?m4FMHzi(3MX|`D?jg_-(URYAvSm|BbrGNCJFtcPCz>Hg?;3g= zWpd*$I%l%R%(v^^#E)6}I@L>zE%8k^=g9aqC|b2KzK)K7trup`I$1y(po~?Ep5s0D zTunilU^JrZXN+c2Arhv>3|olW2=s_~jw)KAwD{iC2TG4WNnx|<4UM{oVZJ0lkXK1l zoM1E`Gj~1y+*!iWsf&!$Ns%pb?Hl z<`hngS;T4{(o4lfSs74IK$YMUXm9EYpdA@bmRrj(V{55PQ34j!0@}WW`N-6pTSjo^ zs|kHSW`eG8Vv-LC>+MZV!QfMlFwVKi@n~f%0DZOjvNOog+{rl3Xfb#C5*7QgCjgOz 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 Wnj<@$ntjj@VI)Lkzf}n7`~4p&g3;9g diff --git a/addons/web/doc/images/tests2.png b/addons/web/doc/images/tests2.png deleted file mode 100644 index c8a6f8ae9eefbeff46a9b45e3a9948676d820714..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20114 zcmaI7b9AM_vo;#r+_5#$p4d(%w#|trwr$(CCz;r`ZD(RzH}gB^J9pi6&-(tUe%|V* zs=ME=e!F_F-eK~xKM>(?;Xpt@5GBM#6hT11P`>aT4A_?xr4BU$0g=^^5D`>%T|LVZ zv^-hG8oI>(`{o78?>G0O*nLYRs}$XdcxQJk7oz_Ms${OXAd;diJQgXnbs35R@GpfS zP~W`H74;?T;?GLh*gQ)cC!g8Wb=MQ3?8K^_sl+0`M@@%=_bVP$K#zVcG5`YnA3#9> zAV38O0`-AkWsh&qSNXqG?7S1=d-x)CBC28NPGd};tgeM(b)I2pKa_)WQKF@)v)b@kSu-j`IRZ0AlHy**naAa7j$B+9Jp8a%oSmUXV9ZgeuEB`3r7$XUjGIzYlD-tSJV zSt$|nR?+c{V@m1@uhT3a{`D$p4sRvSND zaCK7&>30;Gz0aTXGZBb7nwycLJ#z_$AtTsWjzrPcGJ`)7%gIrm{h#fz~71cjpT1a{lh~ABq zNR+87NLm_mO2*fpQXb+rg+uuIZn<~h|HSB)7`jzrbw7?i6_t1{<-Pn`>@ogVh5<9jB90L^7y#p-?akfaA1L4k+n%m)hsV0UX#KePU zdJjH>Ej{29uZBZDeI_Go)MC}*jA=ELbVRRa%<0SRsHdjp1uopF+e+D3dvJ(%ANW-f zq_Dg*zJ2gjB_`oKb>YM``K9KUK!goxV|>lYFMv_$dEkzQ=9X%aWZ(RK-{k7pnZF zmNbF)T9&EOrFLXE8fEGwtw_KnpIlS~`B{6(2zbkGUPzIZ$q&XkdOXolWh+2o3lST@ z`_&iFbp-lU?k}ie1lWUzYFkJ#ea0|h7>(&q>ohj!HKc-Rl>S>y`GN#i877H5Df^2e z{AAp#x`Yz678J#eZ>nbPaj9t)>wWX*;@C+^M^;*fri6DD9LmBVrp$+YT~ElkOTwTq zMu=ej?)Y((+L>H9&%%f>q{T!fHALY14@fc*x&28?In|O8_5q*SjjVk5fTgSLOE-|t zYJCw}tNao1t1Q|LQxA!lOp`F*?B;jc?)rEXYVqq+OJN7H-*iQ(%MSlkmr_(sw)nQQdt5?|||#?_8`uWskN3oyQ={4j5}^6=d)`^uPAe zCP%sE&Qh4P3{c_BC8D7!fK(tpj+o35g%mPyI8&f`aAG5Idd=I_-< z-27d{ZaL=OZT@62kp=sBNLaBNl4njSaMg3-9vJH19XuBilZ;R#y(AqyZpVd1Rs2WV*i$pcMdee6^Jgy)9+4 z&b^SL-02-t*ijf_(U>vfIN(!uQ5>8Hfw4fl1YS__7;!C!5-H*(Qggbj2mCvsP@#6O zVgse@x3yAcipbdT1Fl#mRN%VrgUlbboXQ8oQf>7rpR&u2x=e{}$p!xrJ5oG&?P~g8 z9OdhyqeE}%yHaM({A z^K2g|+*#0EqOHmM?S{PnfFM(r`&di;t&_=JqEZ^YO9g<{6>fKe^R1x)h>UE8jF#I+TTxHO#{cJQ_rR0y&PgDuTM~ys+{Yucz6&J_MWddA3Kk{CV7`UAbZ*v03zlo zJ}w7Sa9$droh0={QdjJm9?xuG*pUoVoo`HkSK)4s{EQsydTkO!T3LHw5 z-gb18Rh#ugn|?fjn}|?|2E&eA{H{$m1l^7?xTUDd`}iD$?vit2Al9Z^3(p1~#Ym$M zInJ9k#V`W)v~E^xI#2q8^YPuBor!#|shnwhufoNcQZb7sNul*ZT-3x^`{nF>x3jPi zCUchApIp=s^z>kPS#H-&UCUL`&kWn( zE7k{k5e%Ubg1;rnXPR#%mCj15f!gz1_`)zT82%-e)3jhUBAbM!vpuFADAp}wUuYC@u3aertBQ_v; zenR>a!}NU7AV>hjF#g04;9rdYHW7q@`qKO_wZ30W6aBQs{tXXbGP);>VTWT^&#oJ;ukhA;C|8md{M`pl zutX?Kr4(r!!>sWAuA9{J+qFQd_V9J-S67wLBJc0--{0ReGBRwS1cI(z*Uz1ASJmt? z_LZZ`mT1%1CP)9=&H6VuuB33x$}(5@ln}F3wo^=fQ!CJfOP8M62^5N#W*za?<8sO7 zgKxv9tT&!uS^HB@5piV8M2J#=Ynw`!aWNNh^Y@}3ihs&DACK1f$}@iyN=G*~nQ^Ew zB*2BK3P#N;ex!X@6`ItO>#J}2!%hWYzWUO_K+URTy0N<)WFo$|j4L9fm(%yx#~R&^ zd^qJQ?kpqr$L3^v z#ha)iccg7k6{ZzZn$gp$%AWtu->G^lE>?$56`#c7*7WN-8dGO=aMTKo&MG}go715F=MJmSbxUKfhB>tB zDJ97KHN_={Cna+J4s6!xv=@a0@_QNQXh1Z>O(N8nQf zT>ih=gGotAsi>%!_<4JOx@2Rsxp}vJzSdMzQ=`}JDu`K%i;ZAzcX=i+F^Gdcl3Q33 zIVmPcA!*QR=UJ_AG5m6OcBUF3$h;uIx3pSy_MIY8qi8ipzSJKhv|LlGP15=={4A6S zO1Va1dDUB3LQ!7twRQd!yOt(1QEms4oM){FIuaFA_ABGbH+rMTu z34+X&yH`q|kpqmI2KurNVn~*nS_?7Mi51A44?s*s|GCwybU*F)z3@)Q!=KqZIu0S@ zGcyYeToZVjQWHVeiNUfr^V*Mj@6=g}EB-EtJv>Wl5Cm+$Gnxq8do3J95Nc(!BNbM zelX^VhiX-a)7*(&Cu0mCxu{9Q=DU&vLDB6QgC5OZ!AL^0MT+d%U0gh^*^45#UGmGT zz{pbm4ijmgg%`UKz5@#c3H`r!BPNI5Q<7l&WUjxss}_7o!?}=s%Cl;Ut(lE9p1$;4 zXByL#l%GAbUu0^>w1%<6DY_loc_@whDKT-3Z{FV6z5P=$S^A7=fKE%UhO33|dxNm0 zw=sev_w!mm!6c;cqs6VWjSL(GzpgO+8;~c^g7<@j{)|v_;Znaz_{8FmG@Z(rvZ$+n zL;3ddGm5Y#Y(YMv0FaUbu(r15$Sdp7%&6Dtxd8r>0H>m|v9j`AnrbNB?q}oOaX(~1 zTdJYbfORnhsv-7proH(0U+s!F_K&|%RtnShX5G4(Yf3USMg*%4srROB!}C4>;Zr3CAv+_fF;a-?By4mi4l7;Dhl&``Zqshz%2 z`pi5nByJbTV-fj$ag#;mDC~0kZWg!n5vOq~l|mYz^+z&KnWkc(w1{enwil_(=_?p4 z=4?5-q=s}FT;h;9e|gc~1#poET0ng!Hj$s?ZB_?Mi2iOewQck8Ka^_;L7c7*yq*d{ z$x#(l761|h63`UJ+ zv5Wg8tGQ~`b-!IR6tKj7)JjE|=#`B;#3{vR+cAxp9fr%42$435SII(2B8m1DK?cJ@ zko6Sjmxg@)b~*4-(9!rnPR-F``5v|sDe-9Y^Ji01bpd_UGCv!yrA!YiWw4a-tg0B>-wrW^WLKQWHN|)` z=(X#HJ_J{;Edu~nCR<8=&w)g!2&Ihz(qAiSLLo@_PE~<>S}<)Oq`XxYaA1KtJ+nCn zC+`P{X$JM%!1eEm4?pMcAH*MtN`ML`vNgbKNjHZ#2q6LNyImDP$;imSSFkQXt~ZAH zKcD4RVUVA~1jk$K4@PgH5oC-I)OJfR^lif5mQ@6qQ_9{iGz*fMFGHR)pH-Zff3}4% zsTeyQlYABj;(hnV* zX`TN#Bcl$BsVqcYTu3r}ZtfGzAQ$-7$sdArrSKzuXRc<)>1bJj7|SYAXbl(#7xsqA zPq-%%5aF0XNt264vl>KCsYwBiz^UK9>}$8v3z<23Tp(N#EZE))Q4yc0(v2deI1Z}v z`!~mFS41nW=U?)--__(^yxiIjd)_0@szo;T4&FmPLyUL4>MH?qE{YE@PD#tR3MAtL zE@f9CFko-4o?M39q%B!2hRHH&C>@z=v^o^9f)-?UVdrbd`W&p*f=t4}mt%9+oakQ2 z=ovO7kWX<)G~+byJmO=|f~V;c1f8B6;NQr>g70s5XK1o^?dxPBugd)gU+btgF7E-Z z6meiM_KiVLS-tmvcnQoXiDwaVyb+h!i)*!7k!bjGB`RX+eZmWTN_Yqh_`YjX1`f_TJ7zXAI#oAQ?{I%Z~R6a^W3zTl1?F>FtKZl{QB~z8M!$7l+4;co7eX# zp%Gd}WPaHvWZ(n$DcS#nyJIuHD*oZGm5}fs%&9;8AJY21FUfzA62OE1i*$~S1N1&k zA#rIL)48xuX`4Rq{Xh7Na=`FU|K%s8?H~T~^B>as|Bci#1}gl|)B3>&Gcq8Da-QAs z7?10&%G!D@=vv-MRE>yz`JS5C>;$B)v1JnzIp&pibQCCroWL+X;=^;Zr|x4b|MO~M z@NIU`>coWJj;3WX0UR!&oDj4l{iSicRGP-D$s*Y2$*%cm*-?=y{^7Xa0Sn@w8g@bh z=p=}eGG87~Lo&CTw?gEb^U1~M?^vuvdq$?GF~h2lPsqxPH^X}&F-48C6`WkU`r-sm zHn?M;W25JNK~KvoQNGmVe8)Nuuh?AFJ5~Jwmn3P=*c7>%U!HtbiqAbtHp3jCV$GVm zQW+*iooe+{-as)e_@@}f{s&vBH1|V6nOeP=d#AXljP)M^m9+frahA<*76GYu60n?i z=ybhPjxWb*u~QxAW5FgX3&Q4JWN7Z1c?dE0IM0afIxsJ66mv+eNxDTrBHt{uz$Q&J zHQe1bv>qnV@E9a~SF?38^u);KwQf{Q*x=!JB{?Nj=9>nJFr*K;&ZebmtaycG@iP{I z)d~C!mP*OeA1zRktS!8~x+e`bTklNI9eu~IQqbc@TSJg~#XUz*rKa#sx@v7Lp9H6< zgxa7(R4TahEt=?uca3i&+!a5qc;H*hn^ii^e-bGEiO#t4dSE|R1$s%nUiU7m?j+9f zdd-Iw`o+Sk9;ov41roJn@;08{ z8G6zmrtGp~`H+%lgM$|`8*9WMx8-WMQrvy3o0EklXJg!DD<=u-&8(ANk0=eCV;gJu z43}-vFz2@N7&>~!wn~FQ9Iv5smxm!CdI%Fm<~Nlxb6P{Z;ux+t7CJYhISKLk#j(;5 z&h=hos&Q@ra$w0f7^A%`PQ2)kYXO#FH@=>zOn%2ZCp90TpXE=Xw!wt3vu-4sBoAm+ zIN}P6PM0>y`{?@Cb)X8>&s^?Fgb9uFj8*9|kW~!Xs8|mP1t(Oq8NAV3Kt=f$Esmjs zr_B2whZiJ^3Yxt7XzN~BC8BGcr+*4~goLuLLw^(A?yuddi=5vOii!pd}(=X)0JRbW%#YAl=xKa5t{Ub1tCG?1>|el4kTP)>s45C zLO$7dSi+xqx%l+%Q&8J%bMk1;>eix$qW)bHlHZxNV(%Dp^1X+dWy8bBVH$r5=JJX> zC-jaJ&wn96_2uVKL(CT0CQ@<9y22x`k+`Z?EkBayrgy>(bM9)3h1T*~_R)8<#(pL! zi)FO=O+13ZJd(cdSXt=QN?vR2;2>@?v%EDYuqWYxtP{9CKm>J`7Kswv@@#dVu@oZ@ zUPm}<2H{kuX^iSG7*3xyS)GmI@{3~iB}FYQZPglvmWybW2P?SPs>qikeBd-!2cL5W zp6wcSG=iAbi|66cud#wr+!wbowueWNx_VDrl`eDFWgyV%FHyfw)KstvPD@U410eWE z1ER?(!~FMEqKimx0p#!)9dL(o#3}FX7PjdSGG+=9x|_$>vlx%hLb$a^=Ot=waOdY| z#+PO5L#8H;94qe)R^K{C=C%~A>NdT%Sv}sv9C{`Q?wd3lAjY{D({^4zL( z1#HKP4Xg?|qYAAFay&xIfGHEWLQZe5C4JmkCkw4t^M%ltm#QtOGSxhzH($+5SeK+57QSx-{Y85tTXFus{%}s z>V(vA@x+i^q>294xefL@A$dRJdg-Ytk<4#LP4xK7c`~+(2?X26sbqi=BwMB4mvN)P z1Ncp@10nvLNPT?y8Jmrgspb(vHpMBbuD;`E3vTvFQdHMWPs4crxRJ53=7+yD!UJm7 z_`uUUU5)RtvGUqJbWVoO66yT0ySVs!-3>o@&@!kw@H233XQ9B6dBY^(5# zWJqr0`r2O!;?M%BlZa|jn|?s}v4|nk!Xl<4xsrdYpTx?FKEQ-VR`-vtxVzck>Pv#W zbLGSH(50XtWY>PyN1sbvphMYM{@k~|?b^nc79-n!$*r?=XAy!XslI#1XpbEgezeDA zn{iWvLjjd^6ou zbCBpc;x3x#rAIF0d_?kT1wIInXytI-8;wL_y8@RBUbBFnq7_;G+pTnt5``R;BYxAh z#LmTLf&X=WupS<3HQbG+=F>k5wIpA#Dz&tk_L2L(GD2%EXphGYmE1=| z&B&&i^-X02d+Y8An)z6{da(DVC467Kw0Ha-HnG0nO7k&&_EG0@Y`mK#F{x6$4qoWD zR8|4Gs^B9;yc5re+~m&~vM63;9M?T|s4T^WJERQpZMhf81pgzb3W{eeZDCIHuJYdj zRvI29`Z7OLINx0@0N?v~GHVZU-IfW}Y&zkL34mABQp}iR?C*zttf4qI*2r@1!}RQ|MIAnh^r{h&a=5rB zeGJ;(D|XQS&}Z^j*uIAjL&Sj*4RbrS41fDFE`;O-r>-aDU#V0YYY{7qI`FZGN&&wM zcn-6r%5s*)5W-62CIZ)9)*4+p(1uLjVWSG9Gw&ZQ+n_k@8u#_=)$z6YM-h8(^c)@n zw)>xHtP>TAi&WA8c`YGbzEfzJ+i41x&bw|iBbL7@@j|v2pD|a%@8$HaIb9?5M8-;o z=cPXris-19JTrKR;EV444*6Jp@f&p>mKw55PS;Ke5rR4Bbi0`Hg7Qqw<`JXkK6$Y} z66d*E%s&ktpBF&uY+8qklKfLz3b7GW`(}uaBm&79 z{cb5p-8GK@0k`*&F?<=y(;NEm-oLx+0=#ZEJ$SN?}vsH|>#7NxlKR0`%_?LVQruP?l zcRrd4%dZe$ADlNFWb zHF6K3$~qQX4f3rUVdSg-`)f1mGTCiNtn^Q!Or`oCs>Uqlfc9o%j-ctAlJRh-G6~KF z&*-@hL~}A9t8o=(Q!Q5pka!QTODFKDt^4|98?;OU;lrL+DIH>vwt4!yh^fxCOg&}8 zFco782f+Jz1!w$J@+q{8n2fO`I$0nUVkjpqkKRUxjbW}KPpr3Cc?idu@aF?(yMfug zl0>IyW2^@&*5UrpewjmkO>po_jid!x>Sz%|J#P&h@RRnfv9(M}N1@R;YwGlu<9Iw0 zpmce)FXYwW#QdH!;V?^G$|BviXh3lZl2DdxOV;|)+f)z1WF@gB#yO?WMA+ZP!~OuQ zv)ritvRS-^q%MBFdRlq|S=G}S29rvv$#SR59gHB!7Lk$rqM^JxcZxevl}jA74-ZtB z*Z7B9DZCqOpt6p(=BII_dV|59THsYPvl1KHlAVl})11Kw$!ZhJ39)|~#Z@yBn~vV& zte#7PB*MC!(Bzn@CK+!VW_G?zbjjVN!qc*yOPi)wq6~)RUHCTD%mk%d-yiZTU*4H#0eHjHIev`uv1hq%uiXQ%wd;>4a3NPS11d^2|Rgz;xW<& z7^!Z6DNN4a`h#5fKF*6f9hPKP8rjBZ4hKGFDFbFcU1O|^96D-_Lfx+Tr|)&udb$n6 z46A!3s>AWP&l89WR6WKCE8!vKbkIDkfbPo}*56$b(7yTVY>XUUTLU(0AZu8tMH3ug zZkSzOBvzxF_;#_CQ868wIYOOcVm`L()aotGCSL6_+;fWz2)q{S$li`I$%@E!*^VCw zL57jXdOL0A^Qo(MItZC0?Np-?SJvY>tbMW_2qieEg9Fg336l)rWH7n%t{)oIOEJ(G zN1Sl^QWuPhxurr+yb=!R3g~ugn|AKA{LO)3Z`74y<0x_gcDzT!+EuB=CGR~2jD`Pg z4I8RcF%6p0EESnAEBCIuP*JM=>)7)2VO{~&)6J2`2RMx&W-T1_ySnLhuEaSBcgS#+ z`Nrn~qETSGs6Z#0igEALcq>Y8x~h|q>g+A{Q_(xFLT$FaZ-nm|cd#SR8SRxh!LC1( zE43ADqu&=a>zN!VH7X@iU_24q{(hoqgAcR0ZohitY$_<7lnl+8KRVKv*AMD0e(e9} zv{snWR`Q;^)^?9D=(KucWWp+U^15KkwF;>m0}RT1>2`UZkxDkx_lhhr+#$YA>OJ^W02py{9jCLysB>sy~1D>YPf5b zJUjvHg_eIe?R`j7sw@|tVK$gk+>|uuV>4iAK0KCr6?0R)hQJuLktFHVyL~u7gC>3D zv#J%M#4EIWr9=zOa@}Tzss#oaoKORkiYL)30HiHa6XJX-JxO5F?C_d&G)!z;y~RIE ztPIobVzZ63n?O2hp%O5*ehbyZ)&DAwA>uqGjMtWB$MRymNYT)#K4@f>rr>L817H2T z8lX|Nl8HkAG&tLPl4_|}Kj)h5>`p|m=SX}jQ&LHU)+wjRuLK)pxuJi&vs1+q$AD+L ziW|7DsoV@Xn|-7lh2PIo8l#Ck!Am}m><%+H%rmUdyYO~8PdVg%kp6frs{3g7cw2qB z1Hm^W@6u92R*K~SJtXIS@kTqS>tJD1HtoKic#{-$554LAN{Enztc0aREqGEYs-+II zmatzJ0?x`Q?@%6u+Dm|Yl-m1fQa{`-RS27M7#$H5tZk(fsc7dGOu57s;<1zPe-z5; zWAg{Ef=Si6S1B=YQHh0yM^NEoTnk}N$tOWsM&$;@zX0##TL7&MymI`591rx3d-pQO zZyEd{sbktPa_8@(5|tK&bgbbohoc;o9UcybbA-h;{+c%0!dx7T4Wl9+`~>fIR#q4~ z#tR9d!hV9s13e?`*aF4zx`uN{j8!cHstS%Y-iJfg%?qhVKCB!SbQ}kZU=JNwwFSZp zsyQ6%-^lWbiJ_V414-w%bUuD!vi@{pIL@quS+i6}rcq+ibJJ0Cqeg^-|W z@L1j%USnvBb~1dM` z75(Zo&mp&TExPo!+KmYpMS;agwECE{x(2f_k*wD_A%&rRCxfpfti0_YiPip0t%h{( z8vRRbCe-b#*x7i|;2vroJoGb!!aLC>Iz9L#!iX=_op_*W@4HOlPHSbQ*1`*Fa(bb> zn30u&Mo(b{*o%AoiM{{!R|32L#GzyU83*Gkukmgc+hKMS6%PXd;fwNIYvRXpOKXWw zNZS-89lTI}E0V529FTaVi{ca|oIMG$$!zW5dqHS?pZws6W%T4xN=Sl>aSr&rC;yql zuFXj)jRs8CvC39&+P03nVO&>0khp=ov)2AjTqcGApoAOJ- znjJc_?|@Qpi{SvLd8Sz@h4TBkLn&XJh~pg&%)mF(e&%NTk2|0`^p7*Z8ZifG;=Pri zAlD%>b!5pplAX#>lpbeV*RjiONBk5L(b>@><$7ndp}F3EUA-eK^)XlB@q43=YY-hM zGyz7LD;d}t6%1g?NU7hr;-^Ig245c3xxjr10$}(_Y{G4V?qd$=dN9Ov&)3*Fmo9la33ui&2c&<7}tqTrGZ;8r>H>NX{5a|zO}~QvY@RaKN2Y7n)T${>0p~zf*6awDNBQ;NPKA1Dx$i&B_C91W?yem*p)r zP*ErsIY9p3%1sRZ%6GqKR$osR`%gbcoC<3i)>2v z38~+Hi&bP}8gAcr&phfSM3@eoJaOK!!mwb#N>49uetwtnS+{dWn;RTZ{Fy+Fs?@c( z#gA6%&sl0Zxf&~;vKdXp#VMxA%N~&)5=1ZK0w2JYV3qrLAq!^guXxb@^VF^?ehj`=E62j+2 z=Ki)}TC)sU6Vh?T%iW#NB-_ZlM628KO1-TQhJfZk*A<(mT};6Xg0Vw7&)`ICeK11} zU)i{ehRJtvo}~abQm=MS5l>I!A5c7|zTc=0$&!mBfZU1{HT397O**lGZaKzYdUN?0 z$aTqAyxf4CTJQ#z3IbVKX;96P$JXu33delD=&vQM>4AE1f7E?MWaBaD=QKKz{lo&( z>kr)@McYYFf`#e{_Vo!1*rxmb!|s^%fTrlk-~d!_K$5-ns+*-7^s1@RyJPr$`0#xw zvxzXZ!=AkqL|qCd6i%OSlj+C;3`n;8^<4Lf! zJo|pIIZ|l1o7)3DOK|uwOCL2uBQ^O|=f&lZD)V*FLIs{2$Hkorhexg>R5WC=ovgf? z3Jih-9M&*7s20lWDp!un!+;RKA9M59FKn$mwrUqw8g(W_`Cy!at$nq)A=pryS>(2DQww3-d!5ryV_c~Zf{3ecmb zX$1zEIYB`hAVr;|mi?dS0dn>t_IWsKOE% zB^nvjx60Nh`T)iwJVHjD`9&Tw*cU}mpkj8l<=Xkr0*5i2q#(x#42*hM(nmAIn_mQk zsxe0{j9#-L7!IqQup*H!Nx?u8+rYPRaxZiqIA(qSQ^STR%?Xb zKyws=65GFclv=h{@Wgw5e$2tl(e9;D0E-?tPndm#!c$)@@LAq%eHYOG;eL~sSes)B3{Soo?t3^#)QrM}8 z7y%4~$YsM3EvfCf0rs%V6c}3XNl_`1@Lpc=8W;&we_s%q;DgY8{s9u(0RQBwn_3ZW zIE9JdTBu+wAo%c9scGLV&UPxVGQ+PT)UKD>Yi(VzDu0XWhUSvTAHE@<+ znU#WN8=HDA)Amh`u|_ZIG}amH=96d;e*d?XzWpbx6Y^(PvdZq$S6=t~^oi(UGMCkj zK5CC>m=U<)a{7DhqV=@A;@7%*ENO$bHcU~|t@{Y~^07LlnS`EJ$^BqheEMpxxTH9& z;KmPnt$Vxx| zWAJD&!f=lz`^_qI9pT$~*h!^7JyxZq>8QFBddZ;25$uhcpj`NLK*IAHrmr+^@Ts>_ zWI0o-)v1T*v-nRNv4vz3xsD0VRDzTX^4A(7KAl%ywKpB9Z}Gn*ComU2O2paK&MdB% zCa1pHS3m8E5aK7kvmTkBL>HVR7| z9)?j5dTu_lJeO?!loFg12_kn}CZ9I2Sd+eO^h`9J;EMEYJ@1)?n3J){n%u4hBK5#J ztp!5s)7*9AOBczBzQxxU1p|T&ADr_f*MJG50j2@{*DTSPg%(2o{k{459xjrEj@9DZW}gp?lpqr1ig+WR{>*(-bEwAF|U__kK9 z@RqD}%ip80`g^fT>Y%ZmRX!uqpO4UPC|!@eL(HbE-~$+)^3D zagW9&*QpC5NE#c0gH>%y?$udp{eV~77}lg!)Z6+4Rm2Zd11_SHBm0ZdGr6r8NtdLQ zn9c*(A455-Inn9?R)$RPWfsGmIi2nX)3(^}OEU}^g-Ji4KGb}zRoqIfv_>gv>4pMuIMV0Ct=V1{JpKP_H%V!K&!g)xYt{a>aWYE zbAHLpI4^>P2vm`4mij6IYk2(;w46w{5e|Nb`h z?j_ePI}l`r6`^HwTqn}==&FeiYoXk8`a_=EipwKbcSC>YShwPG&}y=JHv>4Y@IYyG z#h^wI#J}0(WPVl!*>X_JX~$Z`HK)@!vKJUb>KWw6&choL6@$2V+4V}dT%q)viZ;$s zw@NDrnlom!???{NK2!<}c2SIvnaAnyFp^2r+W*F7Sx7=Nw3<2OCiZ-jZqR=)=7Fud z*6X_^zd`|U`zB~%8(Mu0!1qPK8${f~)Tnb|HgTB#v%UfAz0T>=O6W0D5n5od*VFE{ zY^R3G#KGn)+3_ioBetC2DWQ@=HSVU@x;U0ZngfDw*|hwof`|~1Ob}jpYv{0h5rw%z zW(aRR3S@CgVJvD%jrXh!3$BX|kb`|?H{uH!^yv*9d6YvG#)irqXXqJLf}IT@`>1C2 z0SAxO=`$0b*l5Lc%l;m(dsJmwkC~~zdhutxv9|5R3X5SgtY8KwoZj0qVS!6c0p8k_ zepzjWA>0hm;av*M6ex(&qFk%#x_DOeDlwK*B|UC`J8PcDjUmY56+K~)q-9TnobdFu6j z3lVXz4Y&=Lq~jk~f=2#z(0xfuGpTYYZ%G*c`q!NCD3Bv!(E7?0NWr1DE7(I?XtIm z0f8g#Yw7;$R>+CFF5Q@qQHtq@EEI8t9^&r!LfM)N)=ciNmU341rH`0Z%;@-LU4E-r zq`|%%1AtYB)r7j<_uryl?ecIiuRDs(BDyz};ddeNZaX@U{K&?|FFzgMY6a;AvVnhE zA%K7YBdZ27HB$)S;k7_O5Ws`~-EIFLK@1*Df?*X}Miu9sh2X$r62t{(o#7dLE%S=9 zyQYQjk0o6qk%Xz{XSXc@^Yj}TsSkm2+p=Gy$nkP7J|Hg&(XMf9J3IN zrf)@~kH$F(xxak|(<;ORBvd(t$#rY7i&tJ5NxnQ4bkzaAHdSEcT`1!+@qB`Koh(#N z^ZmlX-A`U~fN@r2+cCG#wiQ=47vKi1Jijm+rR7=iAkwvGzB?U@gy|(K;C`Zi8~vY$ zu3dDf=Z?VRrIGC*oR_y7<6yz1ktb`z99_r^<)SvvG;?`eHWGgg zh+!x=tdW;r)>Qu=Yq2bZ-@v|o+W(lB@Gr>r!k{zCVCNU=1%<}v+6TMPIKdGdodyer zy(vQ(Ieagb0tG=J<28h1gSjVHtV-yCXYR)p%PwsbSQ-Itiap!n{g{PU!73T$goz_h zVm>SpqJhx_S_2w}<%$^Dumf5#zJd;BmT_5NDM7qT7HVSY)Y#R_viNpTw8xQL;~>&q zhSU9HG(Q_d0)>(C^bz?fpo2Ejx}vrBL+dwqiudoj zqa#!OvEk6h1$31}MOYlf5ph(|nW8yE<+%L#-xP|;p;(e&h!$l2QrhVdbglA`JLQDU z<+L}Zv#}3GXPqABYo@OpjRL{)ITdmXxA!ean-2Dy&zroDtb)V_+n4b#s&845v{Mth z-TW3&0>rVvt4m{I6c`9JC@{Z&k6#eXFYpVZz>p)5BYZsw5F7j>fWdQ(6Iei3>!&fdD=z!p$o(Q#!BEFn%%bjg&=wOD;j z?(gk^p<*ZRrcYKQ1lC!hhb4daiF`Z*%kjmnvqY5kCn`TML_p&JyJLqR=j_0kq2G)4QLC<|u8P zM8$}xc>?rp@{a?Bl!c{mpsJeO*7O69v!{u5L37uV5;K|@`2KZCLzoh47)5dh9&oFSDE&5!w&xFW znMp!vDms2f*bN>LFrOU%Nxc_M?X~a!0ZEOBXFWFKF1b8ImlnWQ;+w&VGSx{?K z(MJeF$=N1IHl1|=XP3(!(y$2rDVTQ>% z>Jw1FUbVh{hD99lco<927{8A%upD+QHX&i{yIv^gkiKMCdzT+jKPOfZvu*N@lZn#r zq%kMJs>}k#YM?nsj$QogObI!Snd^ipun>c^z^Tg2X!ZZJah*X;XjvEuB0)L<1BwKt zDJ>FO3=jkpA}B~P3Mddl4UtZ0Aru2j07WT+NI;Pyy$Fba6qO=^QbUm<<ZH>)(pHVX6Ux%aaPVHv6k=n)lFE;~IU zF+6U-%XT`aCbmkPD5Z2FywSJqsjv$5ag2Sh5UqU$OD*+RNZBLW>U{e4qA-5BpdjsB zJiW#Gj7WW4@I?7kL;b@v3yYeql`#A1xt{Za1@!&dUuNmrRsIxQxFGt6?vMQs9};tn z`NRC2WX=QH7BYLL0%5Q>BWqCySO}N3AcK!R<|V_xU27(Ls$d%7DltE8tO&2k9hGr( zk`R^K+RdfDoh>)J((ZWIurvPxAE<+L8oO1S=wLdTz^I=hb^6!B&-Ft+2AO@@u(ER- z&qmhq8imE9_@%o*#AbJA1bC2ADx<#&HUx>zI)1X~A3)3|%$G|p#(POZ8OzUC*xS9x zgE+@F2mZ1MLWWP%YR2O_#6v>1$1I)0by1{bz!Eefz$f zMs1amg8Jv=0MxGLtXI!E1SktZGlK9VHnV9p-jsVZuZ@U;epN^Iq3^0|SFQbkf z)qG#*1>Dx~*uMQ^qEtmHrpgeoZm|Z{0h`;FRyv66jO*eil|Bq>rOyV@pj(kcaiwwV z8RF(uGrB`|=F3N-pQ7x|1Z`GE3K(m8;n*1|b6^NhxR4?$>q7ir$LnxLG*|YrEL~+N zu0$_dV}^Ijv5LX;tN-u7@Pl;ZH#7Myhb#aG#BR}C)PFliaPxdCI!=xg-Ms(maVfL2w!qa8`18HsT zu86@iC5wOE2WGmpzr1P^B={;xL4Pew$C_sDoWvH~L=V@)ZYDjEFB5%O;tnjEK1+YQ zkR2VHFR$21b=WD*lIzsz?^p)hKvm-xfB?044ycu=x1zc@Bt}hfI#ISCt;yYoQj6ns z1>P%H9zO;lz7wEjl(OrKNXH~uTWWhCBx3X)2!ytbNWuIb*EdzFRD&ec&mLQs+|#;-?GehWI~u;0n>;cX0MK2bmVN)$+nk3M{k(}gZWuD zt|Zo7-8kxg_~5$KUpFCE{+9BD?DpgVu;u9MBR)r+N2GJ}MoWhRa4=lcx8%btj?AX~ zjEndpcy&+DiDW2|(#q>G;BywV5FRUwYi^=;bsI8HoASN`o)$l7I}*4uMF9%9T?5lp zblV6PZUK>=b?-60l%+H9_3Rw}lU5<3runAF+J>tlntFVxo_HU6LQYZlfD-}3b1c03KdW6WO(XJKIj95L-K;437_;nT&X1x5 zr9!f4l)nJE<7I2BhB$!OMHpUn$riktGav1qA!pm7nJ;UetYpldHGdstqA|J)2rf_RYCikZ zm;`bgH8pQCiaq?nAS`g;$6xy~IG>`;roK;nUK}P|nAg3e)k05)qyn#9q1n!^rk>1W z(P9rd{EjjJ=iIbO`_}&&Gei0+6S&t0flS%SV`JK5_h~~m*a6=Jb4#NDP0_bc!@D|# zu=W+@l5(M%kRCU*lo6w!G~f9mp|t@__F&zm^0F&j+ z%_cEq#!sSU|B-NEoJP&wOjI&r{_*4m(JXC-^8b2DFeVubHi>% zAMXS!iF}{kEtsc6IQV|u6ihPh^GgWQN@CLV2Ue%1a}$oUc`f>E4nOM12!TTqtrj(Y z92CnIeDtE&D4rVrxqVCbAKLwY>HU9m^-S)A{V%Y?I-j|a^pJz2YQ%vO-0;X!s$|Sz z?cVAM=7`DqftgFA6UT`I2VXnI3e?wxe)v0o zPb3+|71|)H5FjAM{B4eQS^3V&!V!~Zz{0d4!eBNo7CtZ=`+u3x24)qQS>R;_u;|z_ z9UWWpmj=xKN*dyXL$`(z$`QVhX7fdDY@gyW>g#vX^kuD-4S*Sut_(#dIa=zOoYCls zHIaSg>@3!=R{ZF8`}cC;8t!u@Lr;p2FxNB|0I%fsT+DOM&Q>MfOn4xcsT{=^{FY~x zzYu@97Sk;`=!uCcOX^T%VF_C)1>gg_mJla`^Shmcq0oty(iiQw;k~~FTcU5*m@KTj z3T@L0;vc4Rt}N^`S~@PBZ$i|(qtsd7MM_!Sx6k*j;SO-X?y6fuUd3+AbR<0|aGQFC zbX_DP%e(!8KYh6jQqY=tgLrQJW~#=?CODwGV_CpjY;m&=y82G0(%S;Ysm>aDbC(NG zWEehtH4(9#Hs746Zo}rO;+Fc1)GLCHy5;|HuLc=?w#wzFYW;#(^1FSIjEiP{fwSXM z;BcG|MdD=ILW{X1a$VjGh7S9sK3spU@&W6#Xc8Wg3geBy(Akv%g!g>!1FvkKLKw1U zl4b&tl;QJao)?*}PHq|R_>lr!;}z`asUo${0yvTi=&w|wt3>~V_Z@^7`(Sj?2KhRy zV&0kgkY1J1bFX%2tt(7DrnTKN50R^WO=zhL$Z-B@MeB9N0NnT2wPPo37h8YD#nMtz zz4Lh6cD%2%MXsX%E~QOr2G)DwFKk-r+ zHut0y^h>Zz$J0Cq7(@LGl$l;3W8_Jzh4JqFD^r|7S(EJIJTZ?8Q+G!&_QFMJTBz&1 z7D(zhckxN0+~$4XYu?R2%)97Siy*LX(7v6=jlQY9$LYC_c>w&J@72OUan3mx+mvUu z?wCJ2Jt*5&v)ra{kq@>BqU4vS&;Pzo0zYPP@xI1u1t-TJQ+dF<7V`1Th2gPj{x5tp3c9_UIB{ zv;FBuSlHN6CZONQ*M(s#YpLpu`G-ETw3oT74G+fZj$7~N=$U{}iN_)_ht9w#_HDZQHilvC~1vX2-T|chIqI+nDtGp800xnsc2$wQ5(@QZ3cq zd)*O=@)GbcI50p!K=4wMqRK!(AV}Z*Jru|{6{GrT0tBRBCM7DQ>bZKJEo5`LiZOD9 zdHn7RED$&+QS7xPnq7+OMzpg#@f&PV0$KXEq!5C#JS+wYm0cN<65yEJ7+`2s=ZX9p zaoMyIF)`2D!NqSmebe&{FF(2JWFfUE;9b+@;`fFN5!`23i--jV`j0_^!-9hd76KRo zzSF*dzVGyZqu7HU&b=G*|9sx+`OM~y{6qi(+Kz)pfjcO7alHoqZh!AHy`im>>-AsY zZyq!HL3aLcp9JK0zYGA1E#JvCaUUo5^UOCFVEBI~f`D)Rf5IL zI~@*jv|Yy-&TAcOk5`MFt_^YpSF8JyDP}vo`V5xLcxmTa|44xQdZQt2$3Q5+Vp~r< zPiMby%k1yl8UuRg4kA`%Wr9e%C83?SmI-HW6Mr;$OjmSs|L&EqFkDCfad_YOW4lEsHxO|EYR7)Zd8NJ6t&%u@W9beBcR_= zYW2H#$}qXAi1F4t^Or1=(GkuOAIVQjS(izn;ZlP0b?)xRf6a#Lts%j>Sxqx* zEK!g+Mbx&x&$C-SS@My<@4we)&&Z|q=e$Ka3a-)E3+Y-=0YBcI2A6W1bs`%r*yLA+U5g*n894`Hs2V#y0omU|IjX@{SbuxG`K_g~K zdh9%xX7j2kL+X*3#vFrcl|@z7Jm9%|LA~4C`Rvc$PI9@Mo*E!M^T~E`pmL$RZ4qwn z#q{Ly7e&k?X0+%)tvA24=o7XPlEvPEj+7*OwA_J6cS+6N=)Oz~LnwUGK`XsCztNTf z;F(X$C7(Wvk?q%F)#6`^Y6#h=e(l(^*Sm2aZS6}On6n=%WfPrY;eG?4*G1qWitZHk zKVtU}3Mq$h+uJvqmsyvOmKK5%t+T-;qg=Q;oMe{5|5QDkid&qOHC-%7a8GEp*utw;)2+G`|F;=Yw- zsr6_a8IS+6@Re1@=T=N9Dgytiy<)_A&uLvqm6yv8!#;XC)l+9LKw=LUAHuaC2<|xo zel8CZ(lWu?gN5i=NVRxDGh-N!9Zc^wwc<0Tgld*OuBLcJ0I7_SMx2tjCyzY+<6B)q z0bC1=^n-u8X67?eA-oru_up*yl*An=-lL|Ogb+8A&ZZb>5J}kYjKdsW9P|%WjA+XeZ&@uOUNDZ znT;OKE(VJeG?N-B&)3-xf<>YDUVBCVJwosL$`(3iB`_+4GDj4v7&j9t<+9e@i+HavK&Ff-hxO zJ3GKkSe4)?8i2OJ(_cG$Au28%rA%@~GJevDCWB#|E=>07j|ta(G-fD;!0XSi`q#`X zx}PJlxysgI!jR49sJ+x2mE`~KkY{>#C(+wLy!;{xTM=Ab|6`t{lj18HaVAg;dpU zzu3aA!f@;6%rVy?|FX;Cuskrd1==Ohf{Lf88wI3jQD4!Tvt5A7)$4qU9w(|Y74{_$yeG_P$*{HSnSb*r-w-L^ znoH(96WO1zOf1TU3YpX9$OGN7H|4C6w9#|kqRk?|djE}bG-j6)3tC^K(+wt|h8jzBY%}~%`JmWUn2wOG zt^UGNK6FYIJn*5fF^`FUjAhg3Bh+Edhze8FhaXLLIaJS2!?@SkV)!rkJGzVFlRLn7 z1$>=`A?MJvCpB$0s=P)X5HR8ykL?Xb%Q2umJAGSsU$q`xH4$bO&xqGo$1Of*M}J1# zi3ywE$aP@q0_%g|n9&(R*Ix_^$pVchA z+kJ3lq&SJph}`xR*YhEz>+f^xVO|Rhb#v$Y#f}}bj^cc$eN%S-mrU;Al9tZ_7{g=>}-NC@`+VP-o;J{#`<*BPc z^&O0nt?er=L-V5Zvo>|LK1bjayW2ycxL|NWy>+bzQ|9s`K@7HQ>e1xRLImv$_3<)= za0_=8NdN*aXsg9=+XF!m35*yE2@VNN$T2b~Fn1G72r0zyJ@>`Migy3Q#{)Q4E073E z81QW-1O)*VLx^~;6{P+AE_@8S2e|esRQKH%Z z1&jAULEoY1e*;M%D2RWezJG)W>mLOJ{U-m3ME@7x8XTlVhoQ%ix?%tI08|>spAXaN zez#5tvjm6VC~sn;;G%XxavDYb(WQazK(ubT#r6|^F2l{PQeHFBiYu!iCCZ!Qh<-NO z&diS#jgECKM4aJVfYZTWgOwqFGmUxoI5Kj{N!q4EbTt!}}egG1G zi9m!>CE78TMTzOYm&AwWMlelx^rrN?sVXSZ4-XF?A0L^SnGO(wp*NoE7w&hf8cvz} zs=vyXXw%uJ#+&YEgBo2|QaNYkSt|TXh}bJT$){;F3bbJ|WdH7j2q(z0jrkdHd*txL zcHmJom`<{;H8qe&9XT=+AQj*^rqN|y&PClGUk*YDOqk~5(wbiT>Bprojx>h{ zdoWi)Y1k%=b?&M|lK60cx6N?WtpFszP*wz>U6n#Nai9Biwe^*GO^EP%w$b6iXwY2< zqgut2jX?gRN&)a*Z$+zDJjGfyv?P@A>EJ#|SGBO}0aO5A;f?PSaaj5oL^0>un&PZ{ z`>V(cVcSQId4+^}ytbJ#Qh)Z9At>I60L#tQgdwf14=g*%lW?Hp zC|h=HM@}q3mdtZXvz)P?5)TnC5sphl6$mMMEML2dJ6k@3#bK+v2z;r>wR7&v?2J)v zt`tOVFKFj@y1|y4&81t-KdHDqi>zDrYjzA_o36l1khAxz1vs{tt{rGeUwkhfu}F z1yKnv?zrNCUwGO>0Sl{uyqmn%`SpFTRH%NAY$(K>rv1dYc@^anqU-2+9Rx@esd0b@ zGkUm6$OP@BYeF>B1-ecpA|onX;0l-%)Whph;2vfKP0iu!hVr6e)iD@!>;`AZb0bXt zztMwAO--$+sF*ardpKKK;#lI~Ywhm#`#4>=JDM*0=OSYI%WQm_F-{W_?4HjFluoiN@_MX8fEalLaV>wgxR80 zo00{b>RDAeyXEd*%w=p2K^vELA`nw7`*%dc7Q9Rqs%Ban;%)V-7RC7B5b!VTm@S7z z@%&D6>z;>r;Qm-mjT*_>RJ%FJ#ofLt zR`Nr{rmU^@*X)c`PR1F3BVmyWjm~upbK22sq{pTLV_4P!i61|o?% zIra&f+%jE3#LOLhWFcPfcW%c|6gpHZ$g0e1b#|RUDENhfOgIpTZONk}*@61fk_>sh z?n{-+SaIMpRHwZK{TI*NUVqXkHf_SXmyBHQHfp=}8O}YkGFxoIwRDUU(#=-NgPCjQ zbz3Z~>TpyM9KGHCG}7|Qe86Byo>$_YzPwFl=Fi}bsBk|SlqaNa3o2%8LbWLCK}_-? z$6+94u3YqB8D^3YL7L4cfC#t0XGQkmh7Qk#FsJu3d(KHvxoDdz@O95SIO(nYkxl6R z=&3_}iY=$_g+tjOhn%AVhHzptRd|y-pEVUfYy%5tPhmDT$e{A4{^7nn@eEajr}0o? zSg<9rM{a#b7vNgM?(no&sCYZT*4T?UAX2)xM>yMmnWy%F;LcN6tv)fR+$5_OLMd4R z6O)a|RG18)Sp@>XKX9YYcze9g0fj`z=tWsJ4)ujX&V(T#0RAE|V*-3uup` zW>;G`mqsFX5Bx(NjUOU~$V1raZo!Nrgb$$RJ3o}P?1Zym#o0H6AkzV6I*B9c$3 z5;3JvY`{!34BNsxy_lpUo9bK$!0JE(uq8n#d6!9L4(9QcSE!ZkSjaYGGXRIB7kHR% zlZWYtMUxh}ugN_^3lw?H#0m+^SZACY@Zb9j)!<+(mMJtuq32R>%$? ze%Il;F6NE-61TV5A}mlUB3x>It?)x8pWyVuI!%?#+Z&>#gVORd$$J^-LK^GK2kOQO zT@)M)G>D0-4+;#V@!9L)bRm<&!K-HRM1iI-wlv7_Lks{xZoqr%xv;dsO#TyFhiD9T z&WKzCUz3h8*)vrsL(+e}XsEts-t=vhT56gz-IUd3s91#F;stB#`uZ?T2o1cEHGL=SLXYDr`LAd_&;ImPTFOt(G$ zo6ZOmaJ6a*I4t!EwxYCYkTA8uWbw3=XKH%TFtXmGMPPombo($FzeOdysDO4KTpkgb zTOraa;av{!T_>`AAEjI8vAg`j03vDJ)lhm0T`_H9NH{LT&eDMR`1n9uSdV~b`~BRn zcS^eu$oD~_L)|v#gBQ@SVx}-!CsmJH4l%#;^55wb^L`#xN)zc%13pvlG(5Hq8zSj6 z_3ig@{wiT)>xVuD-2f0MF+{hl_$*!p_tLfz^m=DI@k<%Il2qZ!xiF;mo{OX)!w$E^ zA(V)gxqips%hjdd8(ppOoW=BQr}9sA3DrU zo$~v{+T{|_6eG|s`Y}+e5A~~6qWEcPBy{KCSGPI!?E6&Aa`| z1P0?;6MmQ9d0ovxU`0i;3RCC_JHu63rq>HcBb+Hz8%+@y`rD&IfSA~B8IKXy_^D${ z+$OC}yH5cbZDrN^v{q*#p{%Uz>+9Pf_pj$5_E05IEuhI~_FWf-iNz8m1Nl7B_E^v! z@KmQ98}RO{bSLMQ{j6R4KkwaVe@cB}SLuTU-HY#{oVCnNJ9epqn)c$o$>F#J2?nb; zs2IrKbu_AgO7b?=fX+={pX`F31k25l6Mk`g>By-B)5-DJ88u0NR=|Ewyyt*G@1Fd8 z5=2DARA`*)Eki8VDhm#dav+2TOl zoDT6Ys;;Rm*_Yk-!0fDAwBpf!<}%@(W+!_TwTtkBjb5Y@0!km`X5gF?u^Cu&?VS@r z!`AmHINHYK5U`vRGym~ihNE)dihn#L+_&N%j|cd#k-c+o+<%PP#(+isYxEceht=~i z5!bPPz~Ip~p?Cak^1paskxS>)fBbhj6MFyn?{fZQboqZWT0aON{#Vka^H(}#v;yiW zZu>nv{_A3M^F_aBX?uP}Ebh4%8WO8pfaaR+Rb=?c2fCRVR$jOi=Hb2o!HZL+04Ej8 zv$=_%l?nSpeM)PR?%5b{sFYf4fWDlsj-zTZTB8ozfWSNFx{ED$8LHHq>n;~;kn>W= zAzfNK(N7s`wXvi)tBaX)#NKItd_p1axia*}_?pUN8~{RWM$WHef~P_Yw4V+lGOBhT z?SaU9*R|Cxi~>(7$vI>TXF5EuIH%y$>&iP88vdcu3!wR zIDc#x2g%W7*;z^fWwIhH1t`w`xT?kYZ-3`2v`G033iFGbS7XX$l^o4+9MGGDWM2zI z@Lr)Yb}YC*?rBGlHXqFf>d#N}8oQC9`KlDdMqZ=eAvPJnd@~cQAUC9IW`#-6o9Ka$ zn5*dcx+>}4%p>4a$pr1Dt0x%?kWcAf%9%4m!JUe-3TaN)c9mf$T=3nGi!_>Zh$&;_ zY_OKb2v?h^WhlOML5DNe35*!sR$H$8(%(0C?mvn^59_Y>f*9wvT|nm>Lb+=yHrBsl z9-t7b1NIVW;7@g{pk2IlKKHZLSlDyG_0-mBwpbew%Ctx1p84N0U1`(0i#|M!Y%3hc zPjdKAMP~&^!77|-bBy{eb&q?fpj33giBMC|rzuf{MNNw%5&P;ArtYmmUAO%7Y$}d2 zI)<`-iqOKd*EFKHY~7I$itgmA=}!7hQ?)apyuL4W`crOH1nDz}#}3zDJGF zPE%3G7Aj2py$2u6XT19uQWdo?sB>1#Rv$buFBbW|ReL0Wz0X*q3V4t)lVPjMW+%=D zu{`xdh!;O@%3YfZ$+FlLSExJDaqDo5f4mZZ@Xp~OnMoj$-_w`>NDJ5USUM@6vc+6c ze>LA~jNMp_CRDLFgvz9F`-Sq$zSlI%)WuFn%xZW{#+W#$ui-{p!x?s8;gGxVGmvpR@&S|Rpd7R*hyxaN={kMZ zp0m%?E2+y9(iv410RZ}vKWZ-DZtG!HiGVn7%2SkOZqJ#-Ca3;LqT0Ks?$<%z!vNd? z!B=neAa~f!UL+p}m$2-lhQY`Bn_dkWt{tXU8MU;}9N(a{4{T6jEI(GRuA^|QHSSL7 zSv#cLZJSMurSFq}&rT`r)kZtty8Jdh8YtSzoQTralr2}g#6#LPcE)8_9hYT{MTm!I zf`aI47JT2S5Up>6$?C`zvIFFt%4O+W4ii}g|1u#YzeA7I3%25gZWH~v-Siz6tBx@? zD4Q*`_0=zgy_q;8L&*|Q*~J`ohJpTUl?7sYWCM^d_X7C@KX1H(O`O8}Tt>s&+ytY_a?DvSfJ;N3Q<0>2@LMydn37Q!q9u61#b2jbIFNHAXBd>==;{FOuP#5-)zs)0M+ z-!Xm9*%oE^aoBEEJ!DsP$x@`dPC)`a{AC1du@66`IBcL16CW9e=A)Sot*KEXbv*}B-r z60Vs?`wN~loTnJ^ewo)~ha0lT=T~=4MH!Oy_3)u#A7wYDJ}Hq%+i1C5Ac740pVxW( z2=M6KdQagX?FaI&^oeG(lVJ)Cg1qpCXk`tJS3+Eo^&V+zI{Hc3NFV=~;+E#z(5E_h ztg5A+&=hXZL#NCP0#0uO3(=F<>Qzn;k9*H;@V#4IlPcpC@!ua(;RfGG zsaoRpO7@>U`=~)&*g&^pQEjSIcJtnpF~!-MM)YMCa~*b(*qc-O>d`1`v>D0xSY4N% zVrJZF?%W5@`uibycQf94JmAyX=FR?EB^x#aT*snxXbb6$E+3YcyW((U6&I^ zcu#Ol@~K&)EmUdM&4(r>B4$C;E8gSCNhgDh`sp6u> z6u%$zTsbQ0V;i1Ft<>Mh#VRJ0C7oe47Gc(S&bhb;q6f&P=*Q8m>%X3C$V+iE_44m9Nw=$ z_Of+`i;v5O@csV4zQ51uyC(HAk;e+pruPi`b?`-KlW zv4fU`iCZO~T)rRW;PoDy?njMV877;Mle@fYSZaRy?6~v(=r1)n7UJAIc6SDipuf;y1Jj*1COp=wI(>Ar(%fjwm*s(kOK5hFJzx4KOYzH#w;ctf+-3pn2REi`x7Asv(R&DE+;vd6qyJl1xOb}@E-I0-|#j8 zjjv^7TO>N8T{y5Vw)4n*}JEKF|6Kpd|jerVyB+CuZ6G8 z8Q5TfY12cua6L{_%3i~=_!5$qpC=?Tv1qO7+JG-GM!GdD72iW!O=IQ=Uz!%bFkt6b zKpsJT0q=ZhCzxu4k>boOG@IS1D2}zoDG=im5La&N9RnOiaCvvW(Dr*h&F-I!Bt!8#k=tSvi4c$ zp1*?;*GAe!fyuA5Zhv~eLlum1M%(zA@Vb$X)??2?wA-WR4%sy=cD)}U&K4meCA6`l z`x=$E>WGoAVcR%skAJGI1~Pj-&EloDH#cze%oLV?O;mY2Zn8R3Epq!cLLh}G;>*L3 z9*|?`S`(N(J8YmsQ}68uwvuOE{}!%sc;|lLH!!wtONZwpTe3alKA*9f+djj?yc56Q z9CHT64RQyDPvWB{j%zM6(C@{v-b7cnuDdW?J`v7|{w43zdt90J0PQgdTj@ETCBp3I zhomwg^D6brc}IKDMbvzDFT205|GjpKrMnvw#;i>txWGgdQ-({=T|%VYg+1$iUligr zdD(J!bpo{W>J21R(!HOm)N}Y;;1fz3$pvwXq-;=-CV!sG2?sZlNysTrKC&HH=Je2e zm;+0^vNn=9fpCK~A@6mx8-Fqc$*MTKrS2p;bmUA9?EAm-fk8s>@CiyKrwU8&v%38x zN9r*S-{Q|U*FyoH0GePemMR-r~CjTYYm0SX@XWjCVN_jsA!W8 zc(m0%E)~fronhP$n+;6r$>4Oc$^>)k(JeRj&p#Yv6&_;USIAgto(1{}*CX{)V$(d1 zW4i;8U{tW5Zo0WW%PZ}-A{NM76=-DTj07&4KCQ-sF}IrF(J2*qaeL8n*qsFSceN|z zsc7|LZuo*pN@fMTe}WHvV~rV!7!9jg44iT96+&=zYRGZ3W_i*!{YFAs7b_$uoZkD) z#9TK9_m;~W`Yq{INlsPOdNiNPsWn~Ob$z}X)dCF-vlI!VAH?Etl=lQZe;DyB!nqB# z$#qho=kf(qDsi4srI5%*z6z|pIK>x_XbS)prnx>kmoDan@eu`xm9r>fH~N6+5PBfAS#xg2*y)7*xymy1>!4o z?OSzQ&coy^dd1glb&BnGTe{pgXIDIW{%g^x4ygtM9Nc*J!}c^46(GKfLH|%e$fjeM zdb%)OoffNlMum#Kuo>)WUc;$bc%*4xDw*vM7?He#zhGGF@Aaa(kBs`Io=mkv9JoOH z>w=9Srw@0Q&DEhzAbw)8>C`9WGJT?xn%;U;E(Gn1@0@^I@lUr&ASMGOIR@RfKvsaT zgr(9$HGW#mK&lJLkVtFH_p>UCBu^Q8cs1v?%D?M zh5z#|8f|m2Bm|r`4;OztJ>8OzVx!~D;ZWu@S@L`t&3G`w0*aD4unEpfiuWrgEi73i zIQH}C?z4vam5BR^H|hcS?Nr$Tn)n0!guD3mAmC21Zbi|fr~Ogp4&R&N>tj~af0NJ8 z&esbFfhl3Dsw|vZG7HEhfxuTF;&xdd2e+JM``O&Dh=fn{$Id~I10->CUJ(gf&V~zk!IH-HD)#{sp!xUDng`ZUZh2-ba0dSjIfk1mRG4RoZf0q384wz8^+qr zYq9I+WUj~`v+9wON52CybvDEl95G)PGrYykF0MKoP2DvoMm{47juv;3~ym`_f2 z_DF{MQ>nqc-rx7T+xwZYL@H8@btiYJi@HP=RPAU2cP1L^)_?ALaI(}evYc&z-}GUZ z|K?d&DB#&ABP$_|EmMM)HCLNBdyU=u-Q^{E3Irz3gxgRcU_IJNLt#Nfa`03-er-F> z1_k^92VVDB>st{WQuxxMkI&O;H3gLkJbCZ-7~Wz)0L;gi|7@CS9?qyH9*;%&=pTYJ zD>b+~c1rDTd0z!DiIzZxgmVX5v_fH7z;T8j<~A1+c@~B^u+8G$WA#Z^FF9hgaFS_e zsE(gi=GbafNMP%n^$=jckr*QR2?it0{$o z1kz<-=8D8hY$!-=pyQ#W==<_Q zX_&^X#zUom#+qPYS19LA;Xt+H)qmwjjTM`GA8KZ~L5GNSlF>6+g5o>tNl&zGA;|(<+s`PUdP%YqoaPrV5Z%Mfn*r^s$xeyq##_W0w8QFwK(gR%vdjWZ6uf{@B;mPCQR;nrU=arofjW5C98{EgFjQxr(-8VXs zX(?>Z1RdUSPWK<)}lm#^I z)%=?X{|*vuSj9fPwR~^5ChO1EeaDObm_<0^ruAZFI-vfFgy+z3H@_bcMu$XPit5#uT_2E7NXL-f zj6Tzp95pVIywXpNb{p76^7Y(VkAA_{hSwY4U%T@@fce{koqwk01Cwi`1awUFgeR{Q z*>{7f`v#sRU8YWmCFJr+#g;H$h(<;~Kw)uOhToXw+Ue}f_g~%hB7w$f*iZbh9BBDK z7_Wt47W+(iQ~G^mKQn6RX92E)?3PPBBi1-@r3r)JG8pjJagBlh)1%RNk$oQ5o5Eeq znARIZMj6Zp=Ot_pT-oH+FCsaj-q_}i?(DPu5hAt9;Z z{?v^!{>8FZa0aM+V}rW|&YzTM2P)*0LJ$aMU&bk?tH{OzUJPFYrILWcv6=3t-XDKN zB?&MA$8Q@s$jCc^o1-jscM3^y=v1G(fmon_gm}1+S=IVEenZ(qQMHw{+yci6oWdid zc`U4J1dBs?Bsih0|Lqi~t=nz5TH?qVn`6PWs&sz8vuF7VfaUo?s-F0aO-enhhf8nm6KCjfB!5Nxa8!Cu-Y@GZjeg) zS!Qr{MF_3hhd0k+VJBHA<1m7ljYmqK-HT4GI2CD`LkZ)~^J@*Z+lLkGPAX7uxv_7w zR|bjikMyjYVG(^7{(&0^Es@YX?vkk$I6^ccmWXh#CqX6&g$|p^o?Z#B>neHD?1P)KwkET#TNO{rHS-3XpNuyF?tE8>RT{)cjdKca}W>1 z``|OJ4MKO6(p@SZn6TKwTdTY2aJC1bitQ@oA0i)RoBnkSC{R(*cQIMUhV^P z1s@zRqdw5xVf3vOq$ntU;O{L=$T20Yp!GiEHfi>*_BNo#xCmFz(-3DH=vhanM}ObX z^zPGSN(b?eejBbTP$fB-C^#T@|MM}X;Wsh?JeY7O8LY}6{P=yHd)93wCvu`%lDl5E z{yUML+O(I6t~jyNc6L|96p`tjeC^LkI@yU2hK~;IiuC9H(}iD@cpk4bS$vAzpd%m? zoRp;%G+<$5;IO6%0rWq8?XstN-i-5dd$D!Dzp&{Mw9TW0JN>nhG!ZqG zTtGS`K0uFb2S$P>0KGg&L#p{uA|NSC0$#MZJh_{N)mCRwTT&S`oMahxL4bQ1X+cvz z44AP>TA(0vK2A)oB7YzW)YUJ!KtYH!Q2rDkG{5efA!;mWj3D$GL!Iux^cmu36{HxA zXGUEJS8!JCK2@?7Vj+h1EV!fqT*qb%JcTLp!n)~T#I%4~p-f|>OHj1DOsyocf5)Q` zVTb@QswiAAFoNlt>`#d_tzzi@qPPHg$=&2{`~j*>9+@HIunFJ$zjiIxWR>z9Iz%duOf3IX{c?fgsEz4lx z2pley!|i{e|9V?a;Ef?!#la^9DX^6Aq8;PV1~I{~1jEI~VFw_V`0i$gLD!m+*?Zd1 zbH;}p4M`BeK#1Gc?N^b1|D?WI_nhS{j~55&B@IPW`!@V z&tF5UYsv*vtEHPncPmPwue-y!t$2<+!yx(L_lb)nP-VaSHG?iq1JRN{f6M2Dt_^Y` zgwU`~2+K22aIRsKtmHXAD^izghTSB2fM324_rRUC*a2-{A?@K`@)I;p@85CVirYJ) zx5dmXZ}adCViKd{M#sf$5syc;Zre$*aC{JRE7i}vPJ|!f-126^v^Q0c)|A6eP3YgRmKfF!iZhV9O1|u$+pv4<8FiABHUCZq=3Eby9Kd<4!inW9~t>! zBFgPv#||*K>Lk0&qENJ-%x?G;vMK!G05ON`bp(C8q&ZF53rYDDP7Bn=3b*x@pP}aF zIM2K&J)Y9P30E$sQWre*2-svW7`;3~%+32EPyU?s50MmEDoj}PMn91(ipkk@ulM*Z zS>(VY?O%Y>UDn|MK8NJxAOSt4Z^Czl$j8|xpbI?ulAx+sSz5Bm)A))M?WaNG_UlWo z@Ia!*W4F3E_LH@#?Zr^CC`!fSPNw-(u=JT!ZXT9S7wsnn~{5;y-n1x zzrRRg`vam@%y51LOUDspy;R@%-Gjv04Ah2EWWq+a+G01UC7a2 z{qQh|kEzP}XjJRwZ1uk63cS9!UiiEKUL(#-t8^@Hx47~k4C1tWo!cBROqNr=uqdc$ z*cP8N(&NbF*hwPOG3T_ymW9xn-oZt)R-g8-)1?TI>l3lZ;uCg{Lz6mWtEb0Uw{DZo z#IQ=FX(z7qXe#hqnwAI?kTHraiu?2Tq2_{f*G~K-uFtgM-si^^^uV!bd>CL`)m=+G zM>-A^reJ$kQ2D9{jv#HW3%zryHju&q+C4v7gg5zUb2VtS(v#xDCr(^E?tse0Z~n1@B;! zexxE!_*3zt`j+TOyUWWrw9i`>#srMV%uEJ%u7V?GGFpfm5Zy>LAUT=(#L(Fs0xVEa zKLNN^4VvFZ(%WO_1ma?kZg5m18(U4EJp8Rv)PUlvyVApj4>6`b-@?e`rnO=F76FBh zmqB}Q*^}r&x~`O0Y1IHv(a9)sC4Df69&l8df+JuPZ!}YH67Q;SE3eDvf?^}uu9^=g zvZVe}#)_$;-t6`lP%Q15TRqtkzBx##3_EANw;m1q5HfAyoN99?Hqx37ozn?07zyU|9E`uxX==$ey=CO=V4w?cm zdshU%hiKI6pZEWG!=_Cj0C=>@=sNUa_^%0)Jj~rwzxY8@~@7%^5d#+H=wp@YfB$>d7P8)7$RiVk$M z1H~GF7!_BBhpVQbQ=?~~Rs5l!pEf&(vkG#F48eJOBPKur2Y_fn{-wpIY)))M39#=h**^$EU%xn)GalROq^MD zYScAU=sP zBhf}^gI*BAd=Va1iG8pvNMZ5SiPecl{0J~N%rUlT6?F2+E=VL=G#0Y%TU6jqYnOfs zRpwgv+JyACY9~=cL%$iozej31Y$@^iCpUJPX-y*XeO6tc2Lnto=?aa-y!?EX&eyN` ze7;s!>q5yOSEe5Ve!c$7JU!p<-E=W`+7Dl)85>8H^N-YwN=2QjW`yiAO~O(#^-+o` z3573zB4ybRu znef6To?(^b%k{UtQsHcIJ*{(b-23=WXG44gH9qOfG2VmCQQ0JKHrp$D2MAtH9dO1F13Y}NeH|2TE31SJjwU+ zF%%|zUY)SD;-bpG$?STgb;r=uIa8{!!_o`?Zc;JHhgL7kI*EJs^LsgcUkuf zqw=ylx+$8x1#eD$CQS@{j5hANMUVCDK6-2h-yhbLoShu3BtRD!wd3lpnsq0tR()4x z5u4^07Vuj+=?^rzSD(bsaM`amkjt&aW4>F{Q4T*XQsS2_P0@lGs9@G)1pybvsp~8Nf92G3LX_ne= zMG=Z;I_g~R3c~m{k2$p%zMtCkQy4@RN+Vl&$co0HPG1uJ>|F8jro+!4x`4SU!U;D_-z+!=1QR~1q?l0ZG z(WumEzxtjj>)g<~8{KWR_Dz3wT`7REjl%3&);=bRGKilZFH~66OygxbGcRxz^|Njt zRoVqdBSkEGQa>SNc+)U{RVvxy7@%E!t>ng$*et6j@Bq>&gXP)T+4lY7?)C@-VI!U?>t(E}k`mZ}mh; zglw)UwZw*Ck<#o)_k8C()OT^A-P;KNu703UW*%o|!tc6%Mq9nZz~*SZsZx|~b!Jz< z&+c>`oNyBx5B6RG7L(C)tf|LFJHEaQ)$a4PnW)8R?G1-PVy`)|(lsA^Es=QOtq;7|aOi+T$II}|@Y{^JV!^|t76R!DP9{#jdFTi5ebEM;L zbgb+?-(^HRzAQXHlk`5))K2dD^qEJ@Cq%?x>Jo;cKaDef)JV5V)M(gP;`N9mjXM=q z`n8T_!bK2q)y9g0oSqUuc`9eOm>w%X;a46!q`3*X&F>sn_7Mx1h!N&f-6<*`ae747 z(D|@9HkB2+o}8!>a?^lqj>r?f+yjFe7C0e?O7#Ss`$S$8adY!K^aP`D_@vnO*Ge*4 zX$U!nNx!P5Y36My=R&Kx6_bP1JUAUd`@42QGObd+5f5BA+xcL@kK+49f`qH$4N%J5 zrXQoq)CoVT&d&=}&goM4e_6v7jp3Ba?JF^D*ycyMi11w0z3Bz@>7xd=yz-1Z$O~jk z5}N#9Wn6hQ6mIt)k;quHj4^hyGq&sr*=7upbsCJ~YZ#S%9fXKb_C1m{YlEnaYO+&^ zWE4rVkC?Hq^V9o#-*evc`~CAd&w1{-_dMs``}yPZoO5q?tnNrVp-J5t8}^33m(S>{ z&5N=NP7NnJ^#P}4vS+&PD{t+z-_mc`jkL$z85r1BI61hr6#J{TO%1J?W#{#Jc~7ut z?~d!{EQ;(DB(a+sKmyFx>t8rpvCIo)(QnbapznH^Krt2wQHKWn1_goMk(6WGSpL2?va~jxrfdc6kGB+ie6hLFo=OMwT!^)+| z@w}C@9H%opBLk*C!ZIT;K$FxY_kML~7ykCth)gv#y%)QVXDADomzjgEWl?r&^HBk? z$HyYwzue#E`GGAw{YmYJ5cY$tVa zlb0AxCL4-au)~9POk-@UEO9q4<>VS?ef(kF5i(!_Jv&DtiEsHy!ZMm@Um0aTl!N=! zwV54XX_!!{7KV0~9BxZi1>fZ^+0fhNeroE>d0s6EdRrTyDH9+hyv)9ZxOn%m$>BP4 z={zFqr)>6PRGXoT{?~hhpC`8#eB2X4cU(K{3y1gO6tkLV4h9pe7Z{V!Qw2&K#JtK_ z<$hjZVeBH;bttJv@Z6Kw^fFDh|$zZgM7AZU_ZBEALq`?_s#5M!^HOo z4B5kQc`2k>7_wh9mw1>|Uo3Q6+Q}bS{&=9pjfK&UX`*+ri&|>Rx8zNl*de!~8GxRI z)FL>PgcTd8?wbqsSt;R3mh&51CP5RL%i2!_$Fc(^w{APee!dhB zx0tkzi>$9vTk}`>8Yix1FvBb?G7!UB)MtLfc`DXVR5nLLj8DgRv@O|zesHDL$(C)6sy14=*?kuuB7pQ%8 zDX)p%U8y_dV|>S8podc3-$aSggOhLgkT>#UKO3GE@8<@#a~W&-SsCcDEnV>@^QMH~ zeMnj=jljoPM|m4LJ6cA4o-IRWNDuq#4DtdGc^8QvMt(XYs{auyY!8wO-(DcxZMjqu z_`rIXxNWx;x4Rr+2315A^;Fd0*>DMzJEkZn;b;#2629&yObNG9acJ^tu@ZR+Nbm4W zC^J*m%dZ2on+%Im_sn4J%0bH~zHaeA%S-tXrSGB1oJ48Xvn|-VvSnjrcGFwKf_evt zae%4UiEdR0E4D>V8LqvY?(ex@+o0hzFFDj1iCoO;57gvt;l^TqX#3vzZ834>kw@p{ zPREy(7`72{3>+%kW#bHOeRS^3*DF`A^~m{5cr)x2WQ`9to?A@ajI?JGuXAi2;)09? zA^k1ooOwT1piMM-gXd9>6NEbGWb7;xEuO&$^(g18I7j%U*Mt2Bu-I91m~1vgX>uTi z)q={WlorQ{6Zuy(; z53 z5Z?SEaZ98f0UafYG@Cr`_3#Ha_&4`giHOT6Ki09J;?GUz{#bnGPz zvow2sQ2-6akTbY%KobVz1;+_m@WUHy9|8H~mg} zwn%wUTcwG)LCR>)v}K|C;m1wk*}CHsg{E)KGe0%3GPy&K>Yk1JO2a&ed-ZoKMC_D< z@5*#l(D~rfJU&LjVa~AfIj18#d3?I4>691lQHRTwLS|3%^TIym5aYCzA}$?~jwtbSU~+-*VTP^7dL}>(>3lO;v&e&D zx)I`b@^&g_d_X)P0}zXc|Ni7+yUV1_v@~tK$ydS|)#Xa3X|rD{#Xxb;gSg%IVIc*T z?~xWmt={j^@X?jZ)01Cj>~;=@xlV`D2@4XV0;R8QF;1MW$-ZLg%RlL(vcoi7(YrK@ zIRZ`t^0r+99&zHy{2yWSUn=E4n&-d7OU<>T6IcDC#dowrN^i-(gwMCZ=_mwo?_@^* zh=CQXh8ej6t@)!670b9rBTwP60-m5=ivH6B*DZF;=t!vx+1yB-S(aUJG*%Rya?TBi z|LptqX3%SM=W?Q@DA*_N_KO-3a-!;jH}?wK#|Pd}zQS;K_IBuDaTbbuKHI8A&FJWO zg9EZ$yy&7vc(u&QK1Niw`(?aTIteA=AzaHL zR#IHgToE>e6w`R+0^5%HQVHP_tMkCI{(a_5jP;BRx2vww!avvd&(Rxc!k4Ruvh&>o z=i^tk>}9ch&CLfq&T`$imPF;Dz!&v$Dy z5FD9n2=j9unQ?ArkP8mbKf;Aqoe_`l_~E4w0rBX7 zBaj!sf)v)8YrIF4qx`@UrSh3Vj0xWp+LPrq0gPg(hY;D7G{KjAEYNvn)FKHjN61KPuN*>#%4mVo51&7C+lVHds}sUe4Fgv~Mng;Mae6immL znPCZY*ad(h2nYZ&0vPE5adh{HfcIzs8v1Vx#n2_bh$lC`TKT)54q$F`. - -The editable list view module adds a number of methods to the list -view, on top of implementing the :js:class:`EditorDelegate` protocol: - -Interaction Methods -+++++++++++++++++++ - -.. js:function:: openerp.web.ListView.ensure_saved - - Attempts to resolve the pending edition, if any, by saving the - edited row's current state. - - :returns: delegate resolving to all editions having been saved, or - rejected if a pending edition could not be saved - (e.g. validation failure) - -.. js:function:: openerp.web.ListView.start_edition([record][, options]) - - Starts editing the provided record inline, through an overlay form - view of editable fields in the record. - - If no record is provided, creates a new one according to the - editability configuration of the list view. - - This method resolves any pending edition when invoked, before - starting a new edition. - - :param record: record to edit, or null to create a new record - :type record: :js:class:`~openerp.web.list.Record` - :param EditOptions options: - :returns: delegate to the form used for the edition - -.. js:function:: openerp.web.ListView.save_edition - - Resolves the pending edition. - - :returns: delegate to the save being completed, resolves to an - object with two attributes ``created`` (flag indicating - whether the saved record was just created or was - updated) and ``record`` the reloaded record having been - edited. - -.. js:function:: openerp.web.ListView.cancel_edition([force=false]) - - Cancels pending edition, cleans up the list view in case of - creation (removes the empty record being created). - - :param Boolean force: doesn't check if the user has added any - data, discards the edition unconditionally - -Utility Methods -+++++++++++++++ - -.. js:function:: openerp.web.ListView.get_cells_for(row) - - Extracts the cells from a listview row, and puts them in a - {fieldname: cell} mapping for analysis and manipulation. - - :param jQuery row: - :rtype: Object - -.. js:function:: openerp.web.ListView.with_event(event_name, event, action[, args][, trigger_params]) - - Executes ``action`` in the context of the view's editor, - bracketing it with cancellable event signals. - - :param String event_name: base name for the bracketing event, will - be postfixed by ``:before`` and - ``:after`` before being called - (respectively before and after - ``action`` is executed) - :param Object event: object passed to the ``:before`` event - handlers. - :param Function action: function called with the view's editor as - its ``this``. May return a deferred. - :param Array args: arguments passed to ``action`` - :param Array trigger_params: arguments passed to the ``:after`` - event handler alongside the results - of ``action`` - -Behavioral Customizations -+++++++++++++++++++++++++ - -.. js:function:: openerp.web.ListView.handle_onwrite(record) - - Implements the handling of the ``onwrite`` listview attribute: - calls the RPC methods specified by ``@onwrite``, and if that - method returns an array of ids loads or reloads the records - corresponding to those ids. - - :param record: record being written having triggered the - ``onwrite`` callback - :type record: openerp.web.list.Record - :returns: deferred to all reloadings being done - -Events -++++++ - -For simpler interactions by/with external users of the listview, the -view provides a number of dedicated events to its lifecycle. - -.. note:: if an event is defined as *cancellable*, it means its first - parameter is an object on which the ``cancel`` attribute can - be set. If the ``cancel`` attribute is set, the view will - abort its current behavior as soon as possible, and rollback - any state modification. - - Generally speaking, an event should only be cancelled (by - setting the ``cancel`` flag to ``true``), uncancelling an - event is undefined as event handlers are executed on a - first-come-first-serve basis and later handlers may - re-cancel an uncancelled event. - -.. _listview-edit-before: - -``edit:before`` *cancellable* - - Invoked before the list view starts editing a record. - - Provided with an event object with a single property ``record``, - holding the attributes of the record being edited (``record`` is - empty *but not null* for a new record) - -``edit:after`` - - Invoked after the list view has gone into an edition state, - provided with the attributes of the record being edited (see - ``edit:before``) as first parameter and the form used for the - edition as second parameter. - -``save:before`` *cancellable* - - Invoked right before saving a pending edition, provided with an - event object holding the listview's editor (``editor``) and the - edition form (``form``) - -``save:after`` - - Invoked after a save has been completed - -``cancel:before`` *cancellable* - - Invoked before cancelling a pending edition, provided with the - same information as ``save:before``. - -``cancel:after`` - - Invoked after a pending edition has been cancelled. - -DOM events -++++++++++ - -The list view has grown hooks for the ``keyup`` event on its edition -form (during edition): any such event bubbling out of the edition form -will be forwarded to a method ``keyup_EVENTNAME``, where ``EVENTNAME`` -is the name of the key in ``$.ui.keyCode``. - -The method will also get the event object (originally passed to the -``keyup`` handler) as its sole parameter. - -The base editable list view has handlers for the ``ENTER`` and -``ESCAPE`` keys. - -Editor ------- - -The list-edition modules does not generally interact with the embedded -formview, delegating instead to its -:js:class:`~openerp.web.list.Editor`. - -.. js:class:: openerp.web.list.Editor(parent[, options]) - - The editor object provides a more convenient interface to form - views, and simplifies the usage of form views for semi-arbitrary - edition of stuff. - - However, the editor does *not* task itself with being internally - consistent at this point: calling - e.g. :js:func:`~openerp.web.list.Editor.edit` multiple times in a - row without saving or cancelling each edit is undefined. - - :param parent: - :type parent: :js:class:`~openerp.web.Widget` - :param EditorOptions options: - - .. js:function:: openerp.web.list.Editor.is_editing([record_state]) - - Indicates whether the editor is currently in the process of - providing edition for a record. - - Can be filtered by the state of the record being edited - (whether it's a record being *created* or a record being - *altered*), in which case it asserts both that an edition is - underway and that the record being edited respectively does - not yet exist in the database or already exists there. - - :param record_state: state of the record being edited. - Either ``"new"`` or ``"edit"``. - :type record_state: String - :rtype: Boolean - - .. js:function:: openerp.web.list.Editor.edit(record, configureField[, options]) - - Loads the provided record into the internal form view and - displays the form view. - - Will also attempt to focus the first visible field of the form - view. - - :param Object record: record to load into the form view - (key:value mapping similar to the result - of a ``read``) - :param configureField: function called with each field of the - form view right after the form is - displayed, lets whoever called this - method do some last-minute - configuration of form fields. - :type configureField: Function - :param EditOptions options: - :returns: jQuery delegate to the form object - - .. js:function:: openerp.web.list.Editor.save - - Attempts to save the internal form, then hide it - - :returns: delegate to the record under edition (with ``id`` - added for a creation). The record is not updated - from when it was passed in, aside from the ``id`` - attribute. - - .. js:function:: openerp.web.list.Editor.cancel([force=false]) - - Attemps to cancel the edition of the internal form, then hide - the form - - :param Boolean force: unconditionally cancels the edition of - the internal form, even if the user has - already entered data in it. - :returns: delegate to the record under edition - -.. js:class:: EditorOptions - - .. js:attribute:: EditorOptions.formView - - Form view (sub)-class to instantiate and delegate edition to. - - By default, :js:class:`~openerp.web.FormView` - - .. js:attribute:: EditorOptions.delegate - - Object used to get various bits of information about how to - display stuff. - - By default, uses the editor's parent widget. See - :js:class:`EditorDelegate` for the methods and attributes to - provide. - -.. js:class:: EditorDelegate - - Informal protocol defining the methods and attributes expected of - the :js:class:`~openerp.web.list.Editor`'s delegate. - - .. js:attribute:: EditorDelegate.dataset - - The dataset passed to the form view to synchronize the form - view and the outer widget. - - .. js:function:: EditorDelegate.edition_view(editor) - - Called by the :js:class:`~openerp.web.list.Editor` object to - get a form view (JSON) to pass along to the form view it - created. - - The result should be a valid form view, see :doc:`Form Notes - ` for various peculiarities of the form view - format. - - :param editor: editor object asking for the view - :type editor: :js:class:`~openerp.web.list.Editor` - :returns: form view - :rtype: Object - - .. js:function:: EditorDelegate.prepends_on_create - - By default, the :js:class:`~openerp.web.list.Editor` will - append the ids of newly created records to the - :js:attr:`EditorDelegate.dataset`. If this method returns - ``true``, it will prepend these ids instead. - - :returns: whether new records should be prepended to the - dataset (instead of appended) - :rtype: Boolean - - -.. js:class:: EditOptions - - Options object optionally passed into a method starting an edition - to configure its setup and behavior - - .. js:attribute:: focus_field - - Name of the field to set focus on after setting up the edition - of the record. - - If this option is not provided, or the requested field can not - be focused (invisible, readonly or not in the view), the first - visible non-readonly field is focused. - -Changes from 6.1 ----------------- - -* The editable listview behavior has been rewritten pretty much from - scratch, any code touching on editability will have to be modified - - * The overloading of :js:class:`~openerp.web.ListView.Groups` and - :js:class:`~openerp.web.ListView.List` for editability has been - drastically simplified, and most of the behavior has been moved to - the list view itself. Only - :js:func:`~openerp.web.ListView.List.row_clicked` is still - overridden. - - * A new method ``get_row_for(record) -> jQuery(tr) | null`` has been - added to both ListView.List and ListView.Group, it can be called - from the list view to get the table row matching a record (if such - a row exists). - -* :js:func:`~openerp.web.ListView.do_button_action`'s core behavior - has been split away to - :js:func:`~openerp.web.ListView.handle_button`. This allows bypassing - overrides of :js:func:`~openerp.web.ListView.do_button_action` in a - parent class. - - Ideally, :js:func:`~openerp.web.ListView.handle_button` should not be - overridden. - -* Modifiers handling has been improved (all modifiers information - should now be available through :js:func:`~Column.modifiers_for`, - not just ``invisible``) - -* Changed some handling of the list view's record: a record may now - have no id, and the listview will handle that correctly (for new - records being created) as well as correctly handle the ``id`` being - set. - -* Extended the internal collections structure of the list view with - `#find`_, `#succ`_ and `#pred`_. - -.. _#find: http://underscorejs.org/#find - -.. _#succ: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:succ - -.. _#pred: http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#v:pred diff --git a/addons/web/doc/make.bat b/addons/web/doc/make.bat deleted file mode 100644 index 3e72cadb53b..00000000000 --- a/addons/web/doc/make.bat +++ /dev/null @@ -1,170 +0,0 @@ -@ECHO OFF - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set BUILDDIR=_build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% -) - -if "%1" == "" goto help - -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. changes to make an overview over all changed/added/deprecated items - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) - -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\OpenERPWeb.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\OpenERPWeb.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -:end diff --git a/addons/web/doc/module.rst b/addons/web/doc/module.rst deleted file mode 100644 index ca808254567..00000000000 --- a/addons/web/doc/module.rst +++ /dev/null @@ -1,442 +0,0 @@ -.. _module: - -.. queue:: module/series - -Building a Web module -===================== - -There is no significant distinction between a Web module and -a regular module, the web part is mostly additional data and code -inside a regular module. This allows providing more seamless -features by integrating your module deeper into the web client. - -A Basic Module --------------- - -A very basic OpenERP module structure will be our starting point: - -.. code-block:: text - - web_example - ├── __init__.py - └── __manifest__.py - -.. patch:: - -This is a sufficient minimal declaration of a valid module. - -Web Declaration ---------------- - -There is no such thing as a "web module" declaration. An OpenERP -module is automatically recognized as "web-enabled" if it contains a -``static`` directory at its root, so: - -.. code-block:: text - - web_example - ├── __init__.py - ├── __manifest__.py - └── static - -is the extent of it. You should also change the dependency to list -``web``: - -.. patch:: - -.. note:: - - This does not matter in normal operation so you may not realize - it's wrong (the web module does the loading of everything else, so - it can only be loaded), but when e.g. testing the loading process - is slightly different than normal, and incorrect dependency may - lead to broken code. - -This makes the "web" discovery system consider the module as having a -"web part", and check if it has web controllers to mount or javascript -files to load. The content of the ``static/`` folder is also -automatically made available to web browser at the URL -``$module-name/static/$file-path``. This is sufficient to provide -pictures (of cats, usually) through your module. However there are -still a few more steps to running javascript code. - -Getting Things Done -------------------- - -The first one is to add javascript code. It's customary to put it in -``static/src/js``, to have room for e.g. other file types, or -third-party libraries. - -.. patch:: - -The client won't load any file unless specified, thus the new file -should be listed in the module's manifest file, under a new key ``js`` -(a list of file names, or glob patterns): - -.. patch:: - -At this point, if the module is installed and the client reloaded the -message should appear in your browser's development console. - -.. note:: - - Because the manifest file has been edited, you will have to - restart the OpenERP server itself for it to be taken in account. - - You may also want to open your browser's console *before* - reloading, depending on the browser messages printed while the - console is closed may not work or may not appear after opening it. - -.. note:: - - If the message does not appear, try cleaning your browser's caches - and ensure the file is correctly loaded from the server logs or - the "resources" tab of your browser's developers tools. - -At this point the code runs, but it runs only once when the module is -initialized, and it can't get access to the various APIs of the web -client (such as making RPC requests to the server). This is done by -providing a `javascript module`_: - -.. patch:: - -If you reload the client, you'll see a message in the console exactly -as previously. The differences, though invisible at this point, are: - -* All javascript files specified in the manifest (only this one so - far) have been fully loaded -* An instance of the web client and a namespace inside that instance - (with the same name as the module) have been created and are - available for use - -The latter point is what the ``instance`` parameter to the function -provides: an instance of the OpenERP Web client, with the contents of -all the new module's dependencies loaded in and initialized. These are -the entry points to the web client's APIs. - -To demonstrate, let's build a simple :doc:`client action -`: a stopwatch - -First, the action declaration: - -.. patch:: - -then set up the :doc:`client action hook ` to register -a function (for now): - -.. patch:: - -Updating the module (in order to load the XML description) and -re-starting the server should display a new menu *Example Client -Action* at the top-level. Opening said menu will make the message -appear, as usual, in the browser's console. - -Paint it black --------------- - -The next step is to take control of the page itself, rather than just -print little messages in the console. This we can do by replacing our -client action function by a :doc:`widget`. Our widget will simply use -its :js:func:`~openerp.web.Widget.start` to add some content to its -DOM: - -.. patch:: - -after reloading the client (to update the javascript file), instead of -printing to the console the menu item clears the whole screen and -displays the specified message in the page. - -Since we've added a class on the widget's :ref:`DOM root -` we can now see how to add a stylesheet to a module: -first create the stylesheet file: - -.. patch:: - -then add a reference to the stylesheet in the module's manifest (which -will require restarting the OpenERP Server to see the changes, as -usual): - -.. patch:: - -the text displayed by the menu item should now be huge, and -white-on-black (instead of small and black-on-white). From there on, -the world's your canvas. - -.. note:: - - Prefixing CSS rules with both ``.openerp`` (to ensure the rule - will apply only within the confines of the OpenERP Web client) and - a class at the root of your own hierarchy of widgets is strongly - recommended to avoid "leaking" styles in case the code is running - embedded in an other web page, and does not have the whole screen - to itself. - -So far we haven't built much (any, really) DOM content. It could all -be done in :js:func:`~openerp.web.Widget.start` but that gets unwieldy -and hard to maintain fast. It is also very difficult to extend by -third parties (trying to add or change things in your widgets) unless -broken up into multiple methods which each perform a little bit of the -rendering. - -The first way to handle this method is to delegate the content to -plenty of sub-widgets, which can be individually overridden. An other -method [#DOM-building]_ is to use `a template -`_ to render a widget's -DOM. - -OpenERP Web's template language is :doc:`qweb`. Although any -templating engine can be used (e.g. `mustache -`_ or `_.template -`_) QWeb has important features -which other template engines may not provide, and has special -integration to OpenERP Web widgets. - -Adding a template file is similar to adding a style sheet: - -.. patch:: - -The template can then easily be hooked in the widget: - -.. patch:: - -And finally the CSS can be altered to style the new (and more complex) -template-generated DOM, rather than the code-generated one: - -.. patch:: - -.. note:: - - The last section of the CSS change is an example of "state - classes": a CSS class (or set of classes) on the root of the - widget, which is toggled when the state of the widget changes and - can perform drastic alterations in rendering (usually - showing/hiding various elements). - - This pattern is both fairly simple (to read and understand) and - efficient (because most of the hard work is pushed to the - browser's CSS engine, which is usually highly optimized, and done - in a single repaint after toggling the class). - -The last step (until the next one) is to add some behavior and make -our stopwatch watch. First hook some events on the buttons to toggle -the widget's state: - -.. patch:: - -This demonstrates the use of the "events hash" and event delegation to -declaratively handle events on the widget's DOM. And already changes -the button displayed in the UI. Then comes some actual logic: - -.. patch:: - -* An initializer (the ``init`` method) is introduced to set-up a few - internal variables: ``_start`` will hold the start of the timer (as - a javascript Date object), and ``_watch`` will hold a ticker to - update the interface regularly and display the "current time". - -* ``update_counter`` is in charge of taking the time difference - between "now" and ``_start``, formatting as ``HH:MM:SS`` and - displaying the result on screen. - -* ``watch_start`` is augmented to initialize ``_start`` with its value - and set-up the update of the counter display every 33ms. - -* ``watch_stop`` disables the updater, does a final update of the - counter display and resets everything. - -* Finally, because javascript Interval and Timeout objects execute - "outside" the widget, they will keep going even after the widget has - been destroyed (especially an issue with intervals as they repeat - indefinitely). So ``_watch`` *must* be cleared when the widget is - destroyed (then the ``_super`` must be called as well in order to - perform the "normal" widget cleanup). - -Starting and stopping the watch now works, and correctly tracks time -since having started the watch, neatly formatted. - -Burning through the skies -------------------------- - -All work so far has been "local" outside of the original impetus -provided by the client action: the widget is self-contained and, once -started, does not communicate with anything outside itself. Not only -that, but it has no persistence: if the user leaves the stopwatch -screen (to go and see his inbox, or do some well-deserved accounting, -for instance) whatever was being timed will be lost. - -To prevent this irremediable loss, we can use OpenERP's support for -storing data as a model, allowing so that we don't lose our data and -can later retrieve, query and manipulate it. First let's create a -basic OpenERP model in which our data will be stored: - -.. patch:: - -then let's add saving times to the database every time the stopwatch -is stopped, using :js:class:`the "high-level" Model API -`: - -.. patch:: - -A look at the "Network" tab of your preferred browser's developer -tools while playing with the stopwatch will show that the save -(creation) request is indeed sent (and replied to, even though we're -ignoring the response at this point). - -These saved data should now be loaded and displayed when first opening -the action, so the user can see his previously recorded times. This is -done by overloading the model's ``start`` method: the purpose of -:js:func:`~openerp.base.Widget.start()` is to perform *asynchronous* -initialization steps, so the rest of the web client knows to "wait" -and gets a readiness signal. In this case, it will fetch the data -recorded previously using the :js:class:`~openerp.web.Query` interface -and add this data to an ordered list added to the widget's template: - -.. patch:: - -And for consistency's sake (so that the display a user leaves is -pretty much the same as the one he comes back to), newly created -records should also automatically be added to the list: - -.. patch:: - -Note that we're only displaying the record once we know it's been -saved from the database (the ``create`` call has returned without -error). - -Mic check, is this working? ---------------------------- - -So far, features have been implemented, code has been worked and -tentatively tried. However, there is no guarantee they will *keep -working* as new changes are performed, new features added, … - -The original author (you, dear reader) could keep a notebook with a -list of workflows to check, to ensure everything keeps working. And -follow the notebook day after day, every time something is changed in -the module. - -That gets repetitive after a while. And computers are good at doing -repetitive stuff, as long as you tell them how to do it. - -So let's add test to the module, so that in the future the computer -can take care of ensuring what works today keeps working tomorrow. - -.. note:: - - Here we're writing tests after having implemented the widget. This - may or may not work, we may need to alter bits and pieces of code - to get them in a testable state. An other testing methodology is - :abbr:`TDD (Test-Driven Development)` where the tests are written - first, and the code necessary to make these tests pass is written - afterwards. - - Both methods have their opponents and detractors, advantages and - inconvenients. Pick the one you prefer. - -The first step of :doc:`testing` is to set up the basic testing -structure: - -1. Creating a javascript file - - .. patch:: - -2. Containing a test section (and a few tests to make sure the tests - are correctly run) - - .. patch:: - -3. Then declaring the test file in the module's manifest - - .. patch:: - -4. And finally — after restarting OpenERP — navigating to the test - runner at ``/web/tests`` and selecting your soon-to-be-tested - module: - - .. image:: module/testing_0.png - :align: center - - the testing result do indeed match the test. - -The simplest tests to write are for synchronous pure -functions. Synchronous means no RPC call or any other such thing -(e.g. ``setTimeout``), only direct data processing, and pure means no -side-effect: the function takes some input, manipulates it and yields -an output. - -In our widget, only ``format_time`` fits the bill: it takes a duration -(in milliseconds) and returns an ``hours:minutes:second`` formatting -of it. Let's test it: - -.. patch:: - -This series of simple tests passes with no issue. The next easy-ish -test type is to test basic DOM alterations from provided input, such -as (for our widget) updating the counter or displaying a record to the -records list: while it's not pure (it alters the DOM "in-place") it -has well-delimited side-effects and these side-effects come solely -from the provided input. - -Because these methods alter the widget's DOM, the widget needs a -DOM. Looking up :doc:`a widget's lifecycle `, the widget -really only gets its DOM when adding it to the document. However a -side-effect of this is to :js:func:`~openerp.web.Widget.start` it, -which for us means going to query the user's times. - -We don't have any records to get in our test, and we don't want to -test the initialization yet! So let's cheat a bit: we can manually -:js:func:`set a widget's DOM `, let's -create a basic DOM matching what each method expects then call the -method: - -.. patch:: - -The next group of patches (in terms of setup/complexity) is RPC tests: -testing components/methods which perform network calls (RPC -requests). In our module, ``start`` and ``watch_stop`` are in that -case: ``start`` fetches the user's recorded times and ``watch_stop`` -creates a new record with the current watch. - -By default, tests don't allow RPC requests and will generate an error -when trying to perform one: - -.. image:: module/testing_1.png - :align: center - -To allow them, the test case (or the test suite) has to explicitly opt -into :js:attr:`rpc support ` by adding the ``rpc: -'mock'`` option to the test case, and providing its own "rpc -responses": - -.. patch:: - -.. note:: - - By default, tests cases don't load templates either. We had not - needed to perform any template rendering before here, so we must - now enable templates loading via :js:attr:`the corresponding - option `. - -Our final test requires altering the module's code: asynchronous tests -use :doc:`deferred ` to know when a test ends and the other -one can start (otherwise test content will execute non-linearly and -the assertions of a test will be executed during the next test or -worse), but although ``watch_stop`` performs an asynchronous -``create`` operation it doesn't return a deferred we can synchronize -on. We simply need to return its result: - -.. patch:: - -This makes no difference to the original code, but allows us to write -our test: - -.. patch:: - -.. [#DOM-building] they are not alternative solutions: they work very - well together. Templates are used to build "just - DOM", sub-widgets are used to build DOM subsections - *and* delegate part of the behavior (e.g. events - handling). - -.. _javascript module: - http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript diff --git a/addons/web/doc/module/0 b/addons/web/doc/module/0 deleted file mode 100644 index 17b70a86197..00000000000 --- a/addons/web/doc/module/0 +++ /dev/null @@ -1,17 +0,0 @@ -# HG changeset patch -# Parent 0000000000000000000000000000000000000000 - -diff --git a/__init__.py b/__init__.py -new file mode 100644 -diff --git a/__manifest__.py b/__manifest__.py -new file mode 100644 ---- /dev/null -+++ b/__manifest__.py -@@ -0,0 +1,7 @@ -+# __manifest__.py -+{ -+ 'name': "Web Example", -+ 'description': "Basic example of a (future) web module", -+ 'category': 'Hidden', -+ 'depends': ['base'], -+} diff --git a/addons/web/doc/module/10 b/addons/web/doc/module/10 deleted file mode 100644 index dc3b670c5a0..00000000000 --- a/addons/web/doc/module/10 +++ /dev/null @@ -1,13 +0,0 @@ -# HG changeset patch -# Parent 72d9d59a93fcee06ba28cf0b98a1075331dcc8f4 -diff --git a/static/src/css/web_example.css b/static/src/css/web_example.css -new file mode 100644 ---- /dev/null -+++ b/static/src/css/web_example.css -@@ -0,0 +1,6 @@ -+.openerp .oe_web_example { -+ color: white; -+ background-color: black; -+ height: 100%; -+ font-size: 400%; -+} diff --git a/addons/web/doc/module/11 b/addons/web/doc/module/11 deleted file mode 100644 index 889ee98e801..00000000000 --- a/addons/web/doc/module/11 +++ /dev/null @@ -1,11 +0,0 @@ -# HG changeset patch -# Parent 3ed382d9a8fe64fbb8e2bf4045e3fcd5c74c92bc -diff --git a/__manifest__.py b/__manifest__.py ---- a/__manifest__.py -+++ b/__manifest__.py -@@ -6,4 +6,5 @@ - 'depends': ['web'], - 'data': ['web_example.xml'], - 'js': ['static/src/js/first_module.js'], -+ 'css': ['static/src/css/web_example.css'], - } diff --git a/addons/web/doc/module/12 b/addons/web/doc/module/12 deleted file mode 100644 index 85c931c33b2..00000000000 --- a/addons/web/doc/module/12 +++ /dev/null @@ -1,28 +0,0 @@ -# HG changeset patch -# Parent 43f21611dacb7c2b2f3810baeeef359ad7c329f0 - -diff --git a/__manifest__.py b/__manifest__.py ---- a/__manifest__.py -+++ b/__manifest__.py -@@ -7,4 +7,5 @@ - 'data': ['web_example.xml'], - 'js': ['static/src/js/first_module.js'], - 'css': ['static/src/css/web_example.css'], -+ 'qweb': ['static/src/xml/web_example.xml'], - } -diff --git a/static/src/xml/web_example.xml b/static/src/xml/web_example.xml -new file mode 100644 ---- /dev/null -+++ b/static/src/xml/web_example.xml -@@ -0,0 +1,11 @@ -+ -+

-+

00:00:00

-+

-+ -+

-+

-+ -+

-+
-+ diff --git a/addons/web/doc/module/14 b/addons/web/doc/module/14 deleted file mode 100644 index a908cbc61e2..00000000000 --- a/addons/web/doc/module/14 +++ /dev/null @@ -1,17 +0,0 @@ -# HG changeset patch -# Parent ae3b427c96b532794a65357b3f075129cc991276 -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -2,10 +2,6 @@ - openerp.web_example = function (instance) { - instance.web.client_actions.add('example.action', 'instance.web_example.Action'); - instance.web_example.Action = instance.web.Widget.extend({ -- className: 'oe_web_example', -- start: function () { -- this.$el.text("Hello, world!"); -- return this._super(); -- } -+ template: 'web_example.action' - }); - }; diff --git a/addons/web/doc/module/15 b/addons/web/doc/module/15 deleted file mode 100644 index d82abee3284..00000000000 --- a/addons/web/doc/module/15 +++ /dev/null @@ -1,19 +0,0 @@ -# HG changeset patch -# Parent e2d2e1a4cc2d2496aebeb05d94768384427c9e8b -diff --git a/static/src/css/web_example.css b/static/src/css/web_example.css ---- a/static/src/css/web_example.css -+++ b/static/src/css/web_example.css -@@ -2,5 +2,12 @@ - color: white; - background-color: black; - height: 100%; -- font-size: 400%; - } -+.openerp .oe_web_example h4 { -+ margin: 0; -+ font-size: 200%; -+} -+.openerp .oe_web_example.oe_web_example_started .oe_web_example_start button, -+.openerp .oe_web_example.oe_web_example_stopped .oe_web_example_stop button { -+ display: none -+} diff --git a/addons/web/doc/module/16 b/addons/web/doc/module/16 deleted file mode 100644 index 816c23aa0b0..00000000000 --- a/addons/web/doc/module/16 +++ /dev/null @@ -1,25 +0,0 @@ -# HG changeset patch -# Parent 2645d7a09dcba7f6d6074a33252c16c03c56fdf3 -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -2,6 +2,18 @@ - openerp.web_example = function (instance) { - instance.web.client_actions.add('example.action', 'instance.web_example.Action'); - instance.web_example.Action = instance.web.Widget.extend({ -- template: 'web_example.action' -+ template: 'web_example.action', -+ events: { -+ 'click .oe_web_example_start button': 'watch_start', -+ 'click .oe_web_example_stop button': 'watch_stop' -+ }, -+ watch_start: function () { -+ this.$el.addClass('oe_web_example_started') -+ .removeClass('oe_web_example_stopped'); -+ }, -+ watch_stop: function () { -+ this.$el.removeClass('oe_web_example_started') -+ .addClass('oe_web_example_stopped'); -+ }, - }); - }; diff --git a/addons/web/doc/module/17 b/addons/web/doc/module/17 deleted file mode 100644 index d6d6ecc71e3..00000000000 --- a/addons/web/doc/module/17 +++ /dev/null @@ -1,52 +0,0 @@ -# HG changeset patch -# Parent 2921a545adc3406d3139be7951f3225e94493466 -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -7,13 +7,46 @@ openerp.web_example = function (instance - 'click .oe_web_example_start button': 'watch_start', - 'click .oe_web_example_stop button': 'watch_stop' - }, -+ init: function () { -+ this._super.apply(this, arguments); -+ this._start = null; -+ this._watch = null; -+ }, -+ update_counter: function () { -+ var h, m, s; -+ // Subtracting javascript dates returns the difference in milliseconds -+ var diff = new Date() - this._start; -+ s = diff / 1000; -+ m = Math.floor(s / 60); -+ s -= 60*m; -+ h = Math.floor(m / 60); -+ m -= 60*h; -+ this.$('.oe_web_example_timer').text( -+ _.str.sprintf("%02d:%02d:%02d", h, m, s)); -+ }, - watch_start: function () { - this.$el.addClass('oe_web_example_started') - .removeClass('oe_web_example_stopped'); -+ this._start = new Date(); -+ // Update the UI to the current time -+ this.update_counter(); -+ // Update the counter at 30 FPS (33ms/frame) -+ this._watch = setInterval( -+ this.proxy('update_counter'), -+ 33); - }, - watch_stop: function () { -+ clearInterval(this._watch); -+ this.update_counter(); -+ this._start = this._watch = null; - this.$el.removeClass('oe_web_example_started') - .addClass('oe_web_example_stopped'); - }, -+ destroy: function () { -+ if (this._watch) { -+ clearInterval(this._watch); -+ } -+ this._super(); -+ } - }); - }; diff --git a/addons/web/doc/module/18 b/addons/web/doc/module/18 deleted file mode 100644 index 6781c985239..00000000000 --- a/addons/web/doc/module/18 +++ /dev/null @@ -1,19 +0,0 @@ -# HG changeset patch -# Parent e0cc13c2b2ec4d6f6bfdb033b189a32e44106f2e -diff --git a/__init__.py b/__init__.py ---- a/__init__.py -+++ b/__init__.py -@@ -0,0 +1,13 @@ -+# __init__.py -+from openerp.osv import orm, fields -+ -+ -+class Times(orm.Model): -+ _name = 'web_example.stopwatch' -+ -+ _columns = { -+ 'time': fields.integer("Time", required=True, -+ help="Measured time in milliseconds"), -+ 'user_id': fields.many2one('res.users', "User", required=True, -+ help="User who registered the measurement") -+ } diff --git a/addons/web/doc/module/19 b/addons/web/doc/module/19 deleted file mode 100644 index d95a89a3441..00000000000 --- a/addons/web/doc/module/19 +++ /dev/null @@ -1,52 +0,0 @@ -# HG changeset patch -# Parent 05797cc75b49634e640f44b24347f2905b464022 -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -12,11 +12,13 @@ openerp.web_example = function (instance - this._start = null; - this._watch = null; - }, -- update_counter: function () { -+ current: function () { -+ // Subtracting javascript dates returns the difference in milliseconds -+ return new Date() - this._start; -+ }, -+ update_counter: function (time) { - var h, m, s; -- // Subtracting javascript dates returns the difference in milliseconds -- var diff = new Date() - this._start; -- s = diff / 1000; -+ s = time / 1000; - m = Math.floor(s / 60); - s -= 60*m; - h = Math.floor(m / 60); -@@ -29,18 +31,24 @@ openerp.web_example = function (instance - .removeClass('oe_web_example_stopped'); - this._start = new Date(); - // Update the UI to the current time -- this.update_counter(); -+ this.update_counter(this.current()); - // Update the counter at 30 FPS (33ms/frame) -- this._watch = setInterval( -- this.proxy('update_counter'), -+ this._watch = setInterval(function () { -+ this.update_counter(this.current()); -+ }.bind(this), - 33); - }, - watch_stop: function () { - clearInterval(this._watch); -- this.update_counter(); -+ var time = this.current(); -+ this.update_counter(time); - this._start = this._watch = null; - this.$el.removeClass('oe_web_example_started') - .addClass('oe_web_example_stopped'); -+ new instance.web.Model('web_example.stopwatch').call('create', [{ -+ user_id: instance.session.uid, -+ time: time, -+ }]); - }, - destroy: function () { - if (this._watch) { diff --git a/addons/web/doc/module/2 b/addons/web/doc/module/2 deleted file mode 100644 index 7d8e9f05597..00000000000 --- a/addons/web/doc/module/2 +++ /dev/null @@ -1,12 +0,0 @@ -# HG changeset patch -# Parent 8a986919a3e22cd7cca51210820c09d4545dc60d -diff --git a/__manifest__.py b/__manifest__.py ---- a/__manifest__.py -+++ b/__manifest__.py -@@ -3,5 +3,5 @@ - 'name': "Web Example", - 'description': "Basic example of a (future) web module", - 'category': 'Hidden', -- 'depends': ['base'], -+ 'depends': ['web'], - } diff --git a/addons/web/doc/module/20 b/addons/web/doc/module/20 deleted file mode 100644 index 042ff28067c..00000000000 --- a/addons/web/doc/module/20 +++ /dev/null @@ -1,64 +0,0 @@ -Index: web_example/static/src/js/first_module.js -=================================================================== ---- web_example.orig/static/src/js/first_module.js -+++ web_example/static/src/js/first_module.js -@@ -11,20 +11,36 @@ openerp.web_example = function (instance - this._super.apply(this, arguments); - this._start = null; - this._watch = null; -+ this.model = new instance.web.Model('web_example.stopwatch'); -+ }, -+ start: function () { -+ var display = this.display_record.bind(this); -+ return this.model.query() -+ .filter([['user_id', '=', instance.session.uid]]) -+ .all().done(function (records) { -+ _(records).each(display); -+ }); - }, - current: function () { - // Subtracting javascript dates returns the difference in milliseconds - return new Date() - this._start; - }, -- update_counter: function (time) { -+ display_record: function (record) { -+ $('
  • ') -+ .text(this.format_time(record.time)) -+ .appendTo(this.$('.oe_web_example_saved')); -+ }, -+ format_time: function (time) { - var h, m, s; - s = time / 1000; - m = Math.floor(s / 60); - s -= 60*m; - h = Math.floor(m / 60); - m -= 60*h; -- this.$('.oe_web_example_timer').text( -- _.str.sprintf("%02d:%02d:%02d", h, m, s)); -+ return _.str.sprintf("%02d:%02d:%02d", h, m, s); -+ }, -+ update_counter: function (time) { -+ this.$('.oe_web_example_timer').text(this.format_time(time)); - }, - watch_start: function () { - this.$el.addClass('oe_web_example_started') -@@ -45,7 +61,7 @@ openerp.web_example = function (instance - this._start = this._watch = null; - this.$el.removeClass('oe_web_example_started') - .addClass('oe_web_example_stopped'); -- new instance.web.Model('web_example.stopwatch').call('create', [{ -+ this.model.call('create', [{ - user_id: instance.session.uid, - time: time, - }]); -Index: web_example/static/src/xml/web_example.xml -=================================================================== ---- web_example.orig/static/src/xml/web_example.xml -+++ web_example/static/src/xml/web_example.xml -@@ -7,5 +7,6 @@ -

    - -

    -+
      - - diff --git a/addons/web/doc/module/21 b/addons/web/doc/module/21 deleted file mode 100644 index 0acfac9001d..00000000000 --- a/addons/web/doc/module/21 +++ /dev/null @@ -1,27 +0,0 @@ -Index: web_example/static/src/js/first_module.js -=================================================================== ---- web_example.orig/static/src/js/first_module.js -+++ web_example/static/src/js/first_module.js -@@ -55,16 +55,20 @@ openerp.web_example = function (instance - 33); - }, - watch_stop: function () { -+ var self = this; - clearInterval(this._watch); - var time = this.current(); - this.update_counter(time); - this._start = this._watch = null; - this.$el.removeClass('oe_web_example_started') - .addClass('oe_web_example_stopped'); -- this.model.call('create', [{ -+ var record = { - user_id: instance.session.uid, - time: time, -- }]); -+ }; -+ this.model.call('create', [record]).done(function () { -+ self.display_record(record); -+ }); - }, - destroy: function () { - if (this._watch) { diff --git a/addons/web/doc/module/22 b/addons/web/doc/module/22 deleted file mode 100644 index 5df76b303e4..00000000000 --- a/addons/web/doc/module/22 +++ /dev/null @@ -1,6 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- /dev/null -+++ web_example/static/src/tests/timer.js -@@ -0,0 +1 @@ -+ diff --git a/addons/web/doc/module/23 b/addons/web/doc/module/23 deleted file mode 100644 index d08a026a976..00000000000 --- a/addons/web/doc/module/23 +++ /dev/null @@ -1,14 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- web_example.orig/static/src/tests/timer.js -+++ web_example/static/src/tests/timer.js -@@ -1 +1,8 @@ -- -+openerp.testing.section('timer', function (test) { -+ test('successful test', function () { -+ ok(true, "should work"); -+ }); -+ test('unsuccessful test', function () { -+ ok(false, "shoud fail"); -+ }); -+}); diff --git a/addons/web/doc/module/24 b/addons/web/doc/module/24 deleted file mode 100644 index 0972e856042..00000000000 --- a/addons/web/doc/module/24 +++ /dev/null @@ -1,10 +0,0 @@ -Index: web_example/__manifest__.py -=================================================================== ---- web_example.orig/__manifest__.py -+++ web_example/__manifest__.py -@@ -8,4 +8,5 @@ - 'js': ['static/src/js/first_module.js'], - 'css': ['static/src/css/web_example.css'], - 'qweb': ['static/src/xml/web_example.xml'], -+ 'test': ['static/src/tests/timer.js'], - } diff --git a/addons/web/doc/module/25 b/addons/web/doc/module/25 deleted file mode 100644 index 1d63dc7f4a3..00000000000 --- a/addons/web/doc/module/25 +++ /dev/null @@ -1,55 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- web_example.orig/static/src/tests/timer.js -+++ web_example/static/src/tests/timer.js -@@ -1,8 +1,45 @@ - openerp.testing.section('timer', function (test) { -- test('successful test', function () { -- ok(true, "should work"); -- }); -- test('unsuccessful test', function () { -- ok(false, "shoud fail"); -+ test('format_time', function (instance) { -+ var w = new instance.web_example.Action(); -+ -+ strictEqual( -+ w.format_time(0), -+ '00:00:00'); -+ strictEqual( -+ w.format_time(543), -+ '00:00:00', -+ "should round sub-second times down to zero"); -+ strictEqual( -+ w.format_time(5340), -+ '00:00:05', -+ "should floor sub-second extents to the previous second"); -+ strictEqual( -+ w.format_time(60000), -+ '00:01:00'); -+ strictEqual( -+ w.format_time(3600000), -+ '01:00:00'); -+ strictEqual( -+ w.format_time(86400000), -+ '24:00:00'); -+ strictEqual( -+ w.format_time(604800000), -+ '168:00:00'); -+ -+ strictEqual( -+ w.format_time(22733958), -+ '06:18:53'); -+ strictEqual( -+ w.format_time(41676639), -+ '11:34:36'); -+ strictEqual( -+ w.format_time(57802094), -+ '16:03:22'); -+ strictEqual( -+ w.format_time(73451828), -+ '20:24:11'); -+ strictEqual( -+ w.format_time(84092336), -+ '23:21:32'); - }); - }); diff --git a/addons/web/doc/module/26 b/addons/web/doc/module/26 deleted file mode 100644 index ec0b345a908..00000000000 --- a/addons/web/doc/module/26 +++ /dev/null @@ -1,38 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- web_example.orig/static/src/tests/timer.js -+++ web_example/static/src/tests/timer.js -@@ -42,4 +42,33 @@ openerp.testing.section('timer', functio - w.format_time(84092336), - '23:21:32'); - }); -+ test('update_counter', function (instance, $fixture) { -+ var w = new instance.web_example.Action(); -+ // $fixture is a DOM tree whose content gets cleaned up before -+ // each test, so we can add whatever we need to it -+ $fixture.append('
      '); -+ // Then set it on the widget -+ w.setElement($fixture); -+ -+ // Update the counter with a known value -+ w.update_counter(22733958); -+ // And check the DOM matches -+ strictEqual($fixture.text(), '06:18:53'); -+ -+ w.update_counter(73451828) -+ strictEqual($fixture.text(), '20:24:11'); -+ }); -+ test('display_record', function (instance, $fixture) { -+ var w = new instance.web_example.Action(); -+ $fixture.append('
        ') -+ w.setElement($fixture); -+ -+ w.display_record({time: 41676639}); -+ w.display_record({time: 84092336}); -+ -+ var $lis = $fixture.find('li'); -+ strictEqual($lis.length, 2, "should have printed 2 records"); -+ strictEqual($lis[0].textContent, '11:34:36'); -+ strictEqual($lis[1].textContent, '23:21:32'); -+ }); - }); diff --git a/addons/web/doc/module/27 b/addons/web/doc/module/27 deleted file mode 100644 index 2061b7007e6..00000000000 --- a/addons/web/doc/module/27 +++ /dev/null @@ -1,28 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- web_example.orig/static/src/tests/timer.js -+++ web_example/static/src/tests/timer.js -@@ -71,4 +71,23 @@ openerp.testing.section('timer', functio - strictEqual($lis[0].textContent, '11:34:36'); - strictEqual($lis[1].textContent, '23:21:32'); - }); -+ test('start', {templates: true, rpc: 'mock', asserts: 3}, function (instance, $fixture, mock) { -+ // Rather odd-looking shortcut for search+read in a single RPC call -+ mock('/web/dataset/search_read', function () { -+ // ignore parameters, just return a pair of records. -+ return {records: [ -+ {time: 22733958}, -+ {time: 84092336} -+ ]}; -+ }); -+ -+ var w = new instance.web_example.Action(); -+ return w.appendTo($fixture) -+ .then(function () { -+ var $lis = $fixture.find('li'); -+ strictEqual($lis.length, 2); -+ strictEqual($lis[0].textContent, '06:18:53'); -+ strictEqual($lis[1].textContent, '23:21:32'); -+ }); -+ }); - }); diff --git a/addons/web/doc/module/28 b/addons/web/doc/module/28 deleted file mode 100644 index 800e7a6f084..00000000000 --- a/addons/web/doc/module/28 +++ /dev/null @@ -1,13 +0,0 @@ -Index: web_example/static/src/js/first_module.js -=================================================================== ---- web_example.orig/static/src/js/first_module.js -+++ web_example/static/src/js/first_module.js -@@ -66,7 +66,7 @@ openerp.web_example = function (instance - user_id: instance.session.uid, - time: time, - }; -- this.model.call('create', [record]).done(function () { -+ return this.model.call('create', [record]).done(function () { - self.display_record(record); - }); - }, diff --git a/addons/web/doc/module/29 b/addons/web/doc/module/29 deleted file mode 100644 index 509d4b78662..00000000000 --- a/addons/web/doc/module/29 +++ /dev/null @@ -1,37 +0,0 @@ -Index: web_example/static/src/tests/timer.js -=================================================================== ---- web_example.orig/static/src/tests/timer.js -+++ web_example/static/src/tests/timer.js -@@ -90,4 +90,32 @@ openerp.testing.section('timer', functio - strictEqual($lis[1].textContent, '23:21:32'); - }); - }); -+ test('watch_stop', {templates: true, rpc: 'mock', asserts: 3}, function (instance, $fix, mock) { -+ var created = false; -+ mock('web_example.stopwatch:create', function (args, kwargs) { -+ created = true; -+ // return a fake id (unused) -+ return 42; -+ }); -+ mock('/web/dataset/search_read', function () { -+ return {records: []}; -+ }); -+ -+ var w = new instance.web_example.Action(); -+ return w.appendTo($fix) -+ .then(function () { -+ // Virtual start point 5s before 'now' -+ w._start = new Date() - 5000; -+ return w.watch_stop(); -+ }) -+ .done(function () { -+ ok(created, "should have called create()"); -+ strictEqual($fix.find('.oe_web_example_timer').text(), -+ '00:00:05', -+ "should have updated the timer"); -+ strictEqual($fix.find('li')[0].textContent, -+ '00:00:05', -+ "should have added the new time to the list"); -+ }); -+ }); - }); diff --git a/addons/web/doc/module/3 b/addons/web/doc/module/3 deleted file mode 100644 index c09925f93d4..00000000000 --- a/addons/web/doc/module/3 +++ /dev/null @@ -1,9 +0,0 @@ -# HG changeset patch -# Parent dcf661a5eef8f82503831bdb8e6c9d2f9beb285e -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js -new file mode 100644 ---- /dev/null -+++ b/static/src/js/first_module.js -@@ -0,0 +1,2 @@ -+// static/src/js/first_module.js -+console.log("Debug statement: file loaded"); diff --git a/addons/web/doc/module/4 b/addons/web/doc/module/4 deleted file mode 100644 index 99c073d672a..00000000000 --- a/addons/web/doc/module/4 +++ /dev/null @@ -1,11 +0,0 @@ -# HG changeset patch -# Parent 139dae60de67efa0017f5032f71ab774685c5507 -diff --git a/__manifest__.py b/__manifest__.py ---- a/__manifest__.py -+++ b/__manifest__.py -@@ -4,4 +4,5 @@ - 'description': "Basic example of a (future) web module", - 'category': 'Hidden', - 'depends': ['web'], -+ 'js': ['static/src/js/first_module.js'], - } diff --git a/addons/web/doc/module/5 b/addons/web/doc/module/5 deleted file mode 100644 index 49acad9cd52..00000000000 --- a/addons/web/doc/module/5 +++ /dev/null @@ -1,11 +0,0 @@ -# HG changeset patch -# Parent c8ae7646cce3f271698c844eb2d67f9a8719650d -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -1,2 +1,4 @@ - // static/src/js/first_module.js --console.log("Debug statement: file loaded"); -+openerp.web_example = function (instance) { -+ console.log("Module loaded"); -+}; diff --git a/addons/web/doc/module/6 b/addons/web/doc/module/6 deleted file mode 100644 index 3a1232fa51c..00000000000 --- a/addons/web/doc/module/6 +++ /dev/null @@ -1,29 +0,0 @@ -# HG changeset patch -# Parent 0026cb80097a724db8d36371bc00da993a51a06f - -diff --git a/__manifest__.py b/__manifest__.py ---- a/__manifest__.py -+++ b/__manifest__.py -@@ -4,5 +4,6 @@ - 'description': "Basic example of a (future) web module", - 'category': 'Hidden', - 'depends': ['web'], -+ 'data': ['web_example.xml'], - 'js': ['static/src/js/first_module.js'], - } -diff --git a/web_example.xml b/web_example.xml -new file mode 100644 ---- /dev/null -+++ b/web_example.xml -@@ -0,0 +1,11 @@ -+ -+ -+ -+ -+ Example Client Action -+ example.action -+ -+ -+ -+ diff --git a/addons/web/doc/module/8 b/addons/web/doc/module/8 deleted file mode 100644 index 83e6c371bb3..00000000000 --- a/addons/web/doc/module/8 +++ /dev/null @@ -1,14 +0,0 @@ -# HG changeset patch -# Parent d987c9edd884de1de30f2ceb70d2e554474b8dd1 -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -1,4 +1,7 @@ - // static/src/js/first_module.js - openerp.web_example = function (instance) { -- console.log("Module loaded"); -+ instance.web.client_actions.add('example.action', 'instance.web_example.action'); -+ instance.web_example.action = function (parent, action) { -+ console.log("Executed the action", action); -+ }; - }; diff --git a/addons/web/doc/module/9 b/addons/web/doc/module/9 deleted file mode 100644 index 9113f914e7c..00000000000 --- a/addons/web/doc/module/9 +++ /dev/null @@ -1,21 +0,0 @@ -# HG changeset patch -# Parent 6a1a7240ea0e63182f60abb1eb5c631089d56dbe -diff --git a/static/src/js/first_module.js b/static/src/js/first_module.js ---- a/static/src/js/first_module.js -+++ b/static/src/js/first_module.js -@@ -1,7 +1,11 @@ - // static/src/js/first_module.js - openerp.web_example = function (instance) { -- instance.web.client_actions.add('example.action', 'instance.web_example.action'); -- instance.web_example.action = function (parent, action) { -- console.log("Executed the action", action); -- }; -+ instance.web.client_actions.add('example.action', 'instance.web_example.Action'); -+ instance.web_example.Action = instance.web.Widget.extend({ -+ className: 'oe_web_example', -+ start: function () { -+ this.$el.text("Hello, world!"); -+ return this._super(); -+ } -+ }); - }; diff --git a/addons/web/doc/module/series b/addons/web/doc/module/series deleted file mode 100644 index ff1a909a6af..00000000000 --- a/addons/web/doc/module/series +++ /dev/null @@ -1,27 +0,0 @@ -0 -2 -3 -4 -5 -6 -8 -9 -10 -11 -12 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 diff --git a/addons/web/doc/module/testing_0.png b/addons/web/doc/module/testing_0.png deleted file mode 100644 index 62711799ff7320f162a8107fefeed3ad7e1219a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23285 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 B6FL9@ diff --git a/addons/web/doc/module/testing_1.png b/addons/web/doc/module/testing_1.png deleted file mode 100644 index 40cf32497eb0403f11b4b2bd827af9d7bd1ed883..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36183 zcma&N1x#f@(>BO3xVyvP?(T4bK?k_FySuv$?hNkk4uiY9ySux)F7v+m^6&1KP4-D{ zQe9nLZPm}IzBwlpC?f_Bg98Hs0s=1~E+P*C0%`#Q@=X*9^h?unCp!QF5=kH-0#I~a zIm-Z8+>BuiW-&~?zk_;%HYQn)dvKhHt{1~XGi=aG3bvu;fQ6yuhtz=wLP=_%5ktVe zpfF)otD@-yc;|XpkzZp;o20tuJh>8hhZh};adO2zdl*mP`MfWFJT6*ZR|$OH{_z=L z=Ft3eCwq7!rpYDvR{;!qgkkMf zPW)iP{#OBtn(|*wwjc37i~ncAl(ES*S=I_FqdgD#%eCSZ zLszJZq>hi)_=mTP8t%g0U+UoQGm2q8xVr0nj$Foh*1$ZClU`$~X0#fev*t2HbHoJ7 z$LB8n{iJI}T*RBU$$8V}JTFbQ%D|`X`Dox}3JdcAEPIKDQ|_NvF8=CMp%il$-h$>R z#>|G(oBm}1-G2jv_)Wu)O_+YUusWhy36M;h6*@Syd97(B+|9Wzwb!Y|GrPC_or&op z|9}c!fwaiBFYN!czH|&wkqowS7_sE}>S6g{wXkeniT3G`260;(3yx&!N?e}fB!98O z!Q``#80uz~no>o6ec9ndl}hZX3AL#&-@?eWIjJ&MpfdY*T>O`ogkgRiAsK>rct6x+ z_1LK7qf?nVbNgYPVuu&ICgRvldZ!Gp`VR=vMth`%q`C@bwTvr3Z|X6!3dZul;1Fh@ zs_o@<&j8njm(>T!!4FGmFI;UHeIZ91HQGXOBHKgDVSz^q3_$dzBH;NZS4! zJjOpS9BOSvM^=r^08q~-xg(0e1|xAxHQPnYSHG5Qtbjg>nweHiORbfT`K*MXW{Ask z52sjT9vCp_jlfCrK9v4*N6y@A8&+^5A45&**qAff&iEliFMS{uWBvBBzzmdMdafUa zhm50AZfd`c#FTM^kRf#=dxde}ufOay;8?0I8VOS$j#PXE$@iIMePicV?o>n44*P6r zi;_J|Fp}YIfZL^q#seOv?AE_p7zlT}?L-AL&e7)PN|!E4e=sZLGR`Ug_)Rc8pVf00 zG`&-T8~q80Zt>1k-HQ#sH%E&l%}mtR=1U5BEQY_Put5gnA_5NtTH0m2jc8M)bTle7 zkJ?Ww&8Ox*l-IMUm_PDZ6(n&C+Oy*DQkyR(NW>+(dDLnbjV~w&v;8_uNZ?^twcyhR z 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 ^Dqp6?hWlIa;Rb)nA&28sO~dv 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 DeqCyV diff --git a/addons/web/doc/search_view.rst b/addons/web/doc/search_view.rst deleted file mode 100644 index 76692a0d775..00000000000 --- a/addons/web/doc/search_view.rst +++ /dev/null @@ -1,560 +0,0 @@ -Search View -=========== - -OpenERP Web 7.0 implements a unified facets-based search view instead -of the previous form-like search view (composed of buttons and -multiple fields). The goal for this change is twofold: - -* Avoid the common issue of users confusing the search view with a - form view and trying to create their records through it (or entering - all their data, hitting the ``Create`` button expecting their record - to be created and losing everything). - -* Improve the looks and behaviors of the view, and the fit within - OpenERP Web's new design. - -The internal structure of the faceted search is inspired by -`VisualSearch `_ -[#previous]_. - -As does VisualSearch, the new search view is based on `Backbone`_ and -makes significant use of Backbone's models and collections (OpenERP -Web's widgets make a good replacement for Backbone's own views). As a -result, understanding the implementation details of the OpenERP Web 7 -search view also requires a basic understanding of Backbone's models, -collections and events. - -.. note:: - - This document may mention *fetching* data. This is a shortcut for - "returning a :js:class:`Deferred` to [whatever is being - fetched]". Unless further noted, the function or method may opt to - return nothing by fetching ``null`` (which can easily be done by - returning ``$.when(null)``, which simply wraps the ``null`` in a - Deferred). - -Working with the search view: creating new inputs -------------------------------------------------- - -The primary component of search views, as with all other OpenERP -views, are inputs. The search view has two types of inputs — filters -and fields — but only one is easly customizable: fields. - -The mapping from OpenERP field types (and widgets) to search view -objects is stored in the ``openerp.web.search.fields`` -:js:class:`~openerp.web.Registry` where new field types and widgets -can be added. - -Search view inputs have four main roles: - -Loading defaults -++++++++++++++++ - -Once the search view has initialized all its inputs, it will call -:js:func:`~openerp.web.search.Input.facet_for_defaults` on each input, -passing it a mapping (a javascript object) of ``name:value`` extracted -from the action's context. - -This method should fetch a :js:class:`~openerp.web.search.Facet` (or -an equivalent object) for the field's default value if applicable (if -a default value for the field is found in the ``defaults`` mapping). - -A default implementation is provided which checks if ``defaults`` -contains a non-falsy value for the field's ``@name`` and calls -:js:func:`openerp.web.search.Input.facet_for` with that value. - -There is no default implementation of -:js:func:`openerp.web.search.Input.facet_for` [#no_impl]_, but -:js:class:`openerp.web.search.Field` provides one, which uses the -value as-is to fetch a :js:class:`~openerp.web.search.Facet`. - -Providing completions -+++++++++++++++++++++ - -An important component of the new search view is the auto-completion -pane, and the task of providing completion items is delegated to -inputs through the :js:func:`~openerp.web.search.Input.complete` -method. - -This method should take a single argument (the string being typed by -the user) and should fetch an ``Array`` of possible completions -[#completion]_. - -A default implementation is provided which fetches nothing. - -A completion item is a javascript object with two keys (technically it -can have any number of keys, but only these two will be used by the -search view): - -``label`` - - The string which will be displayed in the completion pane. It may - be formatted using HTML (inline only), as a result if ``value`` is - interpolated into it it *must* be escaped. ``_.escape`` can be - used for this. - -``facet`` - - Either a :js:class:`~openerp.web.search.Facet` object or (more - commonly) the corresponding attributes object. This is the facet - which will be inserted into the search query if the completion - item is selected by the user. - -If the ``facet`` is not provided (not present, ``null``, ``undefined`` -or any other falsy value), the completion item will not be selectable -and will act as a section title of sort (the ``label`` will be -formatted differently). If an input *may* fetch multiple completion -items, it *should* prefix those with a section title using its own -name. This has no technical consequence but is clearer for users. - -.. note:: - - If a field is :js:func:`invisible - `, its completion function will - *not* be called. - -Providing drawer/supplementary UI -+++++++++++++++++++++++++++++++++ - -For some inputs (fields or not), interaction via autocompletion may be -awkward or even impossible. - -These may opt to being rendered in a "drawer" as well or instead. In -that case, they will undergo the normal widget lifecycle and be -rendered inside the drawer. - -.. Found no good type-based way to handle this, since there is no MI - (so no type-tagging) and it's possible for both Field and non-Field - input to be put into the drawer, for whatever reason (e.g. some - sort of auto-detector completion item for date widgets, but a - second more usual calendar widget in the drawer for more - obvious/precise interactions) - -Any input can note its desire to be rendered in the drawer by -returning a truthy value from -:js:func:`~openerp.web.search.Input.in_drawer`. - -By default, :js:func:`~openerp.web.search.Input.in_drawer` returns the -value of :js:attr:`~openerp.web.search.Input._in_drawer`, which is -``false``. The behavior can be toggled either by redefining the -attribute to ``true`` (either on the class or on the input), or by -overriding :js:func:`~openerp.web.search.Input.in_drawer` itself. - -The input will be rendered in the full width of the drawer, it will be -started only once (per view). - -.. todo:: drawer API (if a widget wants to close the drawer in some - way), part of the low-level SearchView API/interactions? - - -.. todo:: handle filters and filter groups via a "driver" input which - dynamically collects, lays out and renders filters? => - exercises drawer thingies - -.. note:: - - An :js:func:`invisible ` input - will not be inserted into the drawer. - -Converting from facet objects -+++++++++++++++++++++++++++++ - -Ultimately, the point of the search view is to allow searching. In -OpenERP this is done via :ref:`domains `. On -the other hand, the OpenERP Web 7 search view's state is modelled -after a collection of :js:class:`~openerp.web.search.Facet`, and each -field of a search view may have special requirements when it comes to -the domains it produces [#special]_. - -So there needs to be some way of mapping -:js:class:`~openerp.web.search.Facet` objects to OpenERP search data. - -This is done via an input's -:js:func:`~openerp.web.search.Input.get_domain` and -:js:func:`~openerp.web.search.Input.get_context`. Each takes a -:js:class:`~openerp.web.search.Facet` and returns whatever it's -supposed to generate (a domain or a context, respectively). Either can -return ``null`` if the current value does not map to a domain or -context, and can throw an :js:class:`~openerp.web.search.Invalid` -exception if the value is not valid at all for the field. - -.. note:: - - The :js:class:`~openerp.web.search.Facet` object can have any - number of values (from 1 upwards) - -.. note:: - - There is a third conversion method, - :js:func:`~openerp.web.search.Input.get_groupby`, which returns an - ``Array`` of groupby domains rather than a single context. At this - point, it is only implemented on (and used by) filters. - -Programmatic interactions: internal model ------------------------------------------ - -This new searchview is built around an instance of -:js:class:`~openerp.web.search.SearchQuery` available as -:js:attr:`openerp.web.SearchView.query`. - -The query is a `backbone collection`_ of -:js:class:`~openerp.web.search.Facet` objects, which can be interacted -with directly by external objects or search view controls -(e.g. widgets displayed in the drawer). - -.. js:class:: openerp.web.search.SearchQuery - - The current search query of the search view, provides convenience - behaviors for manipulating :js:class:`~openerp.web.search.Facet` - on top of the usual `backbone collection`_ methods. - - The query ensures all of its facets contain at least one - :js:class:`~openerp.web.search.FacetValue` instance. Otherwise, - the facet is automatically removed from the query. - - .. js:function:: openerp.web.search.SearchQuery.add(values, options) - - Overridden from the base ``add`` method so that adding a facet - which is *already* in the collection will merge the value of - the new facet into the old one rather than add a second facet - with different values. - - :param values: facet, facet attributes or array thereof - :returns: the collection itself - - .. js:function:: openerp.web.search.SearchQuery.toggle(value, options) - - Convenience method for toggling facet values in a query: - removes the values (through the facet itself) if they are - present, adds them if they are not. If the facet itself is not - in the collection, adds it automatically. - - A toggling is atomic: only one change event will be triggered - on the facet regardless of the number of values added to or - removed from the facet (if the facet already exists), and the - facet is only removed from the query if it has no value *at - the end* of the toggling. - - :param value: facet or facet attributes - :returns: the collection - -.. js:class:: openerp.web.search.Facet - - A `backbone model`_ representing a single facet of the current - search. May map to a search field, or to a more complex or - fuzzier input (e.g. a custom filter or an advanced search). - - .. js:attribute:: category - - The displayed name of the facet, as a ``String``. This is a - backbone model attribute. - - .. js:attribute:: field - - The :js:class:`~openerp.web.search.Input` instance which - originally created the facet [#facet-field]_, used to delegate - some operations (such as serializing the facet's values to - domains and contexts). This is a backbone model attribute. - - .. js:attribute:: values - - :js:class:`~openerp.web.search.FacetValues` as a javascript - attribute, stores all the values for the facet and helps - propagate their events to the facet. Is also available as a - backbone attribute (via ``#get`` and ``#set``) in which cases - it serializes to and deserializes from javascript arrays (via - ``Collection#toJSON`` and ``Collection#reset``). - - .. js:attribute:: [icon] - - optional, a single ASCII letter (a-z or A-Z) mapping to the - bundled mnmliconsRegular icon font. - - When a facet with an ``icon`` attribute is rendered, the icon - is displayed (in the icon font) in the first section of the - facet instead of the ``category``. - - By default, only filters make use of this facility. - -.. js:class:: openerp.web.search.FacetValues - - `Backbone collection`_ of - :js:class:`~openerp.web.search.FacetValue` instances. - -.. js:class:: openerp.web.search.FacetValue - - `Backbone model`_ representing a single value within a facet, - represents a pair of (displayed name, logical value). - - .. js:attribute:: label - - Backbone model attribute storing the "displayable" - representation of the value, visually output to the - user. Must be a string. - - .. js:attribute:: value - - Backbone model attribute storing the logical/internal value - (of itself), will be used by - :js:class:`~openerp.web.search.Input` to serialize to domains - and contexts. - - Can be of any type. - -Field services --------------- - -:js:class:`~openerp.web.search.Field` provides a default -implementation of :js:func:`~openerp.web.search.Input.get_domain` and -:js:func:`~openerp.web.search.Input.get_context` taking care of most -of the peculiarities pertaining to OpenERP's handling of fields in -search views. It also provides finer hooks to let developers of new -fields and widgets customize the behavior they want without -necessarily having to reimplement all of -:js:func:`~openerp.web.search.Input.get_domain` or -:js:func:`~openerp.web.search.Input.get_context`: - -.. js:function:: openerp.web.search.Field.get_context(facet) - - If the field has no ``@context``, simply returns - ``null``. Otherwise, calls - :js:func:`~openerp.web.search.Field.value_from` once for each - :js:class:`~openerp.web.search.FacetValue` of the current - :js:class:`~openerp.web.search.Facet` (in order to extract the - basic javascript object from the - :js:class:`~openerp.web.search.FacetValue` then evaluates - ``@context`` with each of these values set as ``self``, and - returns the union of all these contexts. - - :param facet: - :type facet: openerp.web.search.Facet - :returns: a context (literal or compound) - -.. js:function:: openerp.web.search.Field.get_domain(facet) - - If the field has no ``@filter_domain``, calls - :js:func:`~openerp.web.search.Field.make_domain` once with each - :js:class:`~openerp.web.search.FacetValue` of the current - :js:class:`~openerp.web.search.Facet` as well as the field's - ``@name`` and either its ``@operator`` or - :js:attr:`~openerp.web.search.Field.default_operator`. - - If the field has an ``@filter_value``, calls - :js:func:`~openerp.web.search.Field.value_from` once per - :js:class:`~openerp.web.search.FacetValue` and evaluates - ``@filter_value`` with each of these values set as ``self``. - - In either case, "ors" all of the resulting domains (using ``|``) - if there is more than one - :js:class:`~openerp.web.search.FacetValue` and returns the union - of the result. - - :param facet: - :type facet: openerp.web.search.Facet - :returns: a domain (literal or compound) - -.. js:function:: openerp.web.search.Field.make_domain(name, operator, facetValue) - - Builds a literal domain from the provided data. Calls - :js:func:`~openerp.web.search.Field.value_from` on the - :js:class:`~openerp.web.search.FacetValue` and evaluates and sets - it as the domain's third value, uses the other two parameters as - the first two values. - - Can be overridden to build more complex default domains. - - :param String name: the field's name - :param String operator: the operator to use in the field's domain - :param facetValue: - :type facetValue: openerp.web.search.FacetValue - :returns: Array<(String, String, Object)> - -.. js:function:: openerp.web.search.Field.value_from(facetValue) - - Extracts a "bare" javascript value from the provided - :js:class:`~openerp.web.search.FacetValue`, and returns it. - - The default implementation will simply return the ``value`` - backbone property of the argument. - - :param facetValue: - :type facetValue: openerp.web.search.FacetValue - :returns: Object - -.. js:attribute:: openerp.web.search.Field.default_operator - - Operator used to build a domain when a field has no ``@operator`` - or ``@filter_domain``. ``"="`` for - :js:class:`~openerp.web.search.Field` - -Arbitrary data storage ----------------------- - -:js:class:`~openerp.web.search.Facet` and -:js:class:`~openerp.web.search.FacetValue` objects (and structures) -provided by your widgets should never be altered by the search view -(or an other widget). This means you are free to add arbitrary fields -in these structures if you need to (because you have more complex -needs than the attributes described in this document). - -Ideally this should be avoided, but the possibility remains. - -Changes -------- - -.. todo:: merge in changelog instead? - -The displaying of the search view was significantly altered from -OpenERP Web 6.1 to OpenERP Web 7. - -As a result, while the external API used to interact with the search -view does not change many internal details — including the interaction -between the search view and its widgets — were significantly altered: - -Internal operations -+++++++++++++++++++ - -* :js:func:`openerp.web.SearchView.do_clear` has been removed -* :js:func:`openerp.web.SearchView.do_toggle_filter` has been removed - -Widgets API -+++++++++++ - -* :js:func:`openerp.web.search.Widget.render` has been removed - -* :js:func:`openerp.web.search.Widget.make_id` has been removed - -* Search field objects are not openerp widgets anymore, their - ``start`` is not generally called - -* :js:func:`~openerp.web.search.Input.clear` has been removed since - clearing the search view now simply consists of removing all search - facets - -* :js:func:`~openerp.web.search.Input.get_domain` and - :js:func:`~openerp.web.search.Input.get_context` now take a - :js:class:`~openerp.web.search.Facet` as parameter, from which it's - their job to get whatever value they want - -* :js:func:`~openerp.web.search.Input.get_groupby` has been added. It returns - an :js:class:`Array` of context-like constructs. By default, it does not do - anything in :js:class:`~openerp.web.search.Field` and it returns the various - contexts of its enabled filters in - :js:class:`~openerp.web.search.FilterGroup`. - -Filters -+++++++ - -* :js:func:`openerp.web.search.Filter.is_enabled` has been removed - -* :js:class:`~openerp.web.search.FilterGroup` instances are still - rendered (and started) in the "advanced search" drawer. - -Fields -++++++ - -* ``get_value`` has been replaced by - :js:func:`~openerp.web.search.Field.value_from` as it now takes a - :js:class:`~openerp.web.search.FacetValue` argument (instead of no - argument). It provides a default implementation returning the - ``value`` property of its argument. - -* The third argument to - :js:func:`~openerp.web.search.Field.make_domain` is now a - :js:class:`~openerp.web.search.FacetValue` so child classes have all - the information they need to derive the "right" resulting domain. - -Custom filters -++++++++++++++ - -Instead of being an intrinsic part of the search view, custom filters -are now a special case of filter groups. They are treated specially -still, but much less so than they used to be. - -Many To One -+++++++++++ - -* Because the autocompletion service is now provided by the search - view itself, - :js:func:`openerp.web.search.ManyToOneField.setup_autocomplete` has - been removed. - -Advanced Search -+++++++++++++++ - -* The advanced search is now a more standard - :js:class:`~openerp.web.search.Input` configured to be rendered in - the drawer. - -* :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` are - now standard widgets, with the "right" behaviors (they don't rebind - their ``$element`` in ``start()``) - -* The ad-hoc optional setting of the openerp field descriptor on a - :js:class:`~openerp.web.search.ExtendedSearchProposition.Field` has - been removed, the field descriptor is now passed as second argument - to the - :js:class:`~openerp.web.search.ExtendedSearchProposition.Field`'s - constructor, and bound to its - :js:attr:`~openerp.web.search.ExtendedSearchProposition.Field.field`. - -* Instead of its former domain triplet ``(field, operator, value)``, - :js:func:`~openerp.web.search.ExtendedSearchProposition.get_proposition` - now returns an object with two fields ``label`` and ``value``, - respectively a human-readable version of the proposition and the - corresponding domain triplet for the proposition. - -.. [#previous] - - the original view was implemented on top of a monkey-patched - VisualSearch, but as our needs diverged from VisualSearch's goal - this made less and less sense ultimately leading to a clean-room - reimplementation - -.. [#no_impl] - - In case you are extending the search view with a brand new type of - input - -.. [#completion] - - Ideally this array should not hold more than about 10 items, but - the search view does not put any constraint on this at the - moment. Note that this may change. - -.. [#facet-field] - - ``field`` does not actually need to be an instance of - :js:class:`~openerp.web.search.Input`, nor does it need to be what - created the facet, it just needs to provide the three - facet-serialization methods - :js:func:`~openerp.web.search.Input.get_domain`, - :js:func:`~openerp.web.search.Input.get_context` and - :js:func:`~openerp.web.search.Input.get_gropuby`, existing - :js:class:`~openerp.web.search.Input` subtypes merely provide - convenient base implementation for those methods. - - Complex search view inputs (especially those living in the drawer) - may prefer using object literals with the right slots returning - closed-over values or some other scheme un-bound to an actual - :js:class:`~openerp.web.search.Input`, as - :js:class:`~openerp.web.search.CustomFilters` and - :js:class:`~openerp.web.search.Advanced` do. - -.. [#special] - - search view fields may also bundle context data to add to the - search context - -.. _Backbone: - http://documentcloud.github.com/backbone/ - -.. _Backbone.Collection: -.. _Backbone collection: - http://documentcloud.github.com/backbone/#Collection - -.. _Backbone model: - http://documentcloud.github.com/backbone/#Model - -.. _commit 3fca87101d: - https://github.com/documentcloud/visualsearch/commit/3fca87101d