liquid_feedback_frontend
changeset 1045:701a5cf6b067
Imported LiquidFeedback Frontend 3.0 branch
author | bsw |
---|---|
date | Thu Jul 10 01:19:48 2014 +0200 (2014-07-10) |
parents | a6c7bf07badb |
children | b9300c2e75da |
files | INSTALL.html INSTALL.mkd LICENSE app/main/_filter/21_auth.lua app/main/_filter_view/30_navigation.lua app/main/_layout/default.html app/main/_layout/system_error.html app/main/admin/_action/area_update.lua app/main/admin/area_show.lua app/main/admin/cancel_issue.lua app/main/admin/index.lua app/main/admin/member_edit.lua app/main/admin/member_list.lua app/main/admin/policy_list.lua app/main/admin/policy_show.lua app/main/admin/unit_edit.lua app/main/area/_head.lua app/main/area/_issue_list.lua app/main/area/_sidebar_members.lua app/main/area/_sidebar_whatcanido.lua app/main/area/show.lua app/main/contact/list.lua app/main/delegation/_info.lua app/main/delegation/_list.lua app/main/delegation/show.lua app/main/delegation/show_incoming.lua app/main/draft/_action/add.lua app/main/draft/diff.lua app/main/draft/list.lua app/main/draft/new.lua app/main/draft/show.lua app/main/event/_list.lua app/main/help/introduction.lua app/main/index/404.lua app/main/index/_action/login.lua app/main/index/_login.lua app/main/index/_motd.lua app/main/index/_sidebar_members.lua app/main/index/_sidebar_motd_intern.lua app/main/index/_sidebar_motd_public.lua app/main/index/_sidebar_notifications.lua app/main/index/_sidebar_units.lua app/main/index/_sidebar_whatcanido.lua app/main/index/about.lua app/main/index/check_delegations.lua app/main/index/document.lua app/main/index/download.lua app/main/index/email_unconfirmed.lua app/main/index/index.lua app/main/index/login.lua app/main/index/notifications.lua app/main/index/register.lua app/main/index/reset_password.lua app/main/index/search.lua app/main/index/send_login.lua app/main/index/usage_terms.lua app/main/initiative/_action/add_support.lua app/main/initiative/_action/create.lua app/main/initiative/_action/remove_support.lua app/main/initiative/_bargraph.lua app/main/initiative/_battles.lua app/main/initiative/_head.lua app/main/initiative/_initiators.lua app/main/initiative/_list.lua app/main/initiative/_list_element.lua app/main/initiative/_show.lua app/main/initiative/_sidebar_history.lua app/main/initiative/_sidebar_policies.lua app/main/initiative/_sidebar_state.lua app/main/initiative/_sidebar_support.lua app/main/initiative/_sidebar_wikisyntax.lua app/main/initiative/add_initiator.lua app/main/initiative/history.lua app/main/initiative/new.lua app/main/initiative/remove_initiator.lua app/main/initiative/revoke.lua app/main/initiative/show.lua app/main/interest/_action/update.lua app/main/interest/show_incoming.lua app/main/issue/_details.lua app/main/issue/_filters.lua app/main/issue/_head.lua app/main/issue/_head2.lua app/main/issue/_list.lua app/main/issue/_list2.lua app/main/issue/_show.lua app/main/issue/_sidebar_issue.lua app/main/issue/_sidebar_members.lua app/main/issue/_sidebar_state.lua app/main/issue/_sidebar_whatcanido.lua app/main/issue/history.lua app/main/issue/list.lua app/main/issue/show.lua app/main/member/_action/update.lua app/main/member/_event_list.lua app/main/member/_list.lua app/main/member/_profile.lua app/main/member/_show.lua app/main/member/_show_thumb.lua app/main/member/_sidebar_contacts.lua app/main/member/_sidebar_whatcanido.lua app/main/member/developer_settings.lua app/main/member/edit.lua app/main/member/edit_images.lua app/main/member/history.lua app/main/member/list.lua app/main/member/settings.lua app/main/member/settings_email.lua app/main/member/settings_login.lua app/main/member/settings_name.lua app/main/member/settings_notification.lua app/main/member/settings_password.lua app/main/member/show.lua app/main/membership/_action/update.lua app/main/opinion/_action/update.lua app/main/policy/_list.lua app/main/policy/list.lua app/main/slideshow/_index.lua app/main/slideshow/_slideshow.lua app/main/slideshow/index.lua app/main/suggestion/_action/add.lua app/main/suggestion/new.lua app/main/supporter/show_incoming.lua app/main/timeline/_action/delete_filter.lua app/main/timeline/_action/save.lua app/main/timeline/_action/update.lua app/main/timeline/_constants.lua app/main/timeline/_filter/29_filter.lua app/main/timeline/_list.lua app/main/timeline/index.lua app/main/timeline/list_filter.lua app/main/timeline/save_filter.lua app/main/unit/_head.lua app/main/unit/_list.lua app/main/unit/_sidebar.lua app/main/unit/_sidebar_members.lua app/main/unit/_sidebar_whatcanido.lua app/main/unit/list.lua app/main/unit/show.lua app/main/vote/_action/update.lua app/main/vote/list.lua app/main/vote/show_incoming.lua config/devel.lua config/example.lua config/init.lua config/lf3.lua env/format/interval_text.lua env/format/wiki_text.lua env/model/has_rendered_content.lua env/ui/actions.lua env/ui/bargraph.lua env/ui/contextbar.lua env/ui/delegation.lua env/ui/filters.lua env/ui/raw_title.lua env/ui/section.lua env/ui/sectionHead.lua env/ui/sectionRow.lua env/ui/sidebar.lua env/ui/sidebarHead.lua env/ui/sidebarHeadWhatCanIDo.lua env/ui/sidebarSection.lua env/ui/title.lua env/ui/titleAdmin.lua env/ui/titleMember.lua env/util/help.lua env/util/initiative_pie.lua env/util/micro_avatar.lua locale/Makefile locale/help/area.show.de.txt locale/help/area.show.el.txt locale/help/area.show.en.txt locale/help/area.show.zh-Hans.txt locale/help/area.show.zh-TW.txt locale/help/contact.list.de.txt locale/help/contact.list.el.txt locale/help/contact.list.en.txt locale/help/contact.list.eo.txt locale/help/contact.list.zh-Hans.txt locale/help/contact.list.zh-TW.txt locale/help/delegation.new.area.de.txt locale/help/delegation.new.area.el.txt locale/help/delegation.new.area.en.txt locale/help/delegation.new.area.eo.txt locale/help/delegation.new.area.zh-Hans.txt locale/help/delegation.new.area.zh-TW.txt locale/help/delegation.new.issue.de.txt locale/help/delegation.new.issue.el.txt locale/help/delegation.new.issue.en.txt locale/help/delegation.new.issue.eo.txt locale/help/delegation.new.issue.zh-Hans.txt locale/help/delegation.new.issue.zh-TW.txt locale/help/delegation.new.unit.de.txt locale/help/delegation.new.unit.el.txt locale/help/delegation.new.unit.en.txt locale/help/delegation.new.unit.zh-Hans.txt locale/help/delegation.new.unit.zh-TW.txt locale/help/index.check_delegations.de.txt locale/help/index.check_delegations.en.txt locale/help/index.check_delegations_hard.de.txt locale/help/index.check_delegations_hard.en.txt locale/help/index.download.de.txt locale/help/index.download.el.txt locale/help/index.download.en.txt locale/help/index.download.eo.txt locale/help/index.download.zh-Hans.txt locale/help/index.download.zh-TW.txt locale/help/index.index.de.txt locale/help/index.index.el.txt locale/help/index.index.en.txt locale/help/index.index.zh-Hans.txt locale/help/index.index.zh-TW.txt locale/help/initiative.add_initiator.de.txt locale/help/initiative.add_initiator.el.txt locale/help/initiative.add_initiator.en.txt locale/help/initiative.add_initiator.eo.txt locale/help/initiative.add_initiator.zh-Hans.txt locale/help/initiative.add_initiator.zh-TW.txt locale/help/initiative.remove_initiator.de.txt locale/help/initiative.remove_initiator.el.txt locale/help/initiative.remove_initiator.en.txt locale/help/initiative.remove_initiator.eo.txt locale/help/initiative.remove_initiator.zh-Hans.txt locale/help/initiative.remove_initiator.zh-TW.txt locale/help/initiative.revoke.de.txt locale/help/initiative.revoke.el.txt locale/help/initiative.revoke.en.txt locale/help/initiative.revoke.eo.txt locale/help/initiative.revoke.zh-Hans.txt locale/help/initiative.revoke.zh-TW.txt locale/help/initiative.show.de.txt locale/help/initiative.show.el.txt locale/help/initiative.show.en.txt locale/help/initiative.show.eo.txt locale/help/initiative.show.zh-Hans.txt locale/help/initiative.show.zh-TW.txt locale/help/issue.show.de.txt locale/help/issue.show.el.txt locale/help/issue.show.en.txt locale/help/issue.show.zh-Hans.txt locale/help/issue.show.zh-TW.txt locale/help/member.edit.de.txt locale/help/member.edit.el.txt locale/help/member.edit.en.txt locale/help/member.edit.eo.txt locale/help/member.edit.zh-Hans.txt locale/help/member.edit.zh-TW.txt locale/help/member.edit_images.de.txt locale/help/member.edit_images.el.txt locale/help/member.edit_images.en.txt locale/help/member.edit_images.eo.txt locale/help/member.edit_images.zh-Hans.txt locale/help/member.edit_images.zh-TW.txt locale/help/member.settings.email_address.de.txt locale/help/member.settings.email_address.el.txt locale/help/member.settings.email_address.en.txt locale/help/member.settings.email_address.zh-Hans.txt locale/help/member.settings.email_address.zh-TW.txt locale/help/member.settings.login.de.txt locale/help/member.settings.login.el.txt locale/help/member.settings.login.en.txt locale/help/member.settings.login.eo.txt locale/help/member.settings.login.zh-Hans.txt locale/help/member.settings.login.zh-TW.txt locale/help/member.settings.name.de.txt locale/help/member.settings.name.el.txt locale/help/member.settings.name.en.txt locale/help/member.settings.name.eo.txt locale/help/member.settings.name.zh-Hans.txt locale/help/member.settings.name.zh-TW.txt locale/help/member.settings.notification.de.txt locale/help/member.settings.notification.el.txt locale/help/member.settings.notification.en.txt locale/help/member.settings.notification.zh-Hans.txt locale/help/member.settings.notification.zh-TW.txt locale/help/member.settings.password.de.txt locale/help/member.settings.password.el.txt locale/help/member.settings.password.en.txt locale/help/member.settings.password.eo.txt locale/help/member.settings.password.zh-Hans.txt locale/help/member.settings.password.zh-TW.txt locale/help/member.show.de.txt locale/help/member.show.el.txt locale/help/member.show.en.txt locale/help/member.show.eo.txt locale/help/member.show.zh-Hans.txt locale/help/member.show.zh-TW.txt locale/help/policy.list.de.txt locale/help/policy.list.el.txt locale/help/policy.list.en.txt locale/help/policy.list.eo.txt locale/help/policy.list.zh-Hans.txt locale/help/policy.list.zh-TW.txt locale/help/vote.list.de.txt locale/help/vote.list.el.txt locale/help/vote.list.en.txt locale/help/vote.list.eo.txt locale/help/vote.list.zh-Hans.txt locale/help/vote.list.zh-TW.txt locale/help/wikisyntax.en.txt locale/help/wikisyntax_compat.en.txt locale/help/wikisyntax_rocketwiki.en.txt locale/translations.de.lua model/battle.lua model/contact.lua model/initiative.lua model/issue.lua model/member.lua static/back.png static/back50.png static/icons/16/chart_organisation.png static/icons/32/empty.png static/icons/32/phase_current.png static/icons/32/phase_failed.png static/icons/32/phase_finished.png static/icons/32/support_none.png static/icons/32/support_satisfied.png static/icons/32/support_satisfied_via_delegation.png static/icons/32/support_unsatisfied.png static/icons/32/support_unsatisfied_via_delegation.png static/icons/32/voted_no.png static/icons/48/bell.png static/icons/48/eye.png static/icons/48/home.png static/icons/48/info.png static/icons/48/lf_plus.png static/icons/48/star.png static/icons/48/star_empty.png static/icons/48/voted_ok.png static/js/less-1.4.1.min.js static/lf3.css static/lf3.less static/star.png static/style.css utils/optparse.lua |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/INSTALL.html Thu Jul 10 01:19:48 2014 +0200 1.3 @@ -0,0 +1,191 @@ 1.4 +<html> 1.5 +<head> 1.6 + <title>LiquidFeedback Installation Instructions</title> 1.7 + <style type="text/css">code{white-space: pre;}</style> 1.8 +</head> 1.9 +<body> 1.10 +<h1 id="liquidfeedback-installation-instructions">LiquidFeedback Installation Instructions</h1> 1.11 +<p>This document gives a short outline about the necessary steps to setup a LiquidFeedback system.</p> 1.12 +<h2 id="install-necessary-dependencies">1. Install necessary dependencies</h2> 1.13 +<p>If you're using a Debian system, make sure that the following packages are installed:</p> 1.14 +<ul> 1.15 +<li>lua5.1</li> 1.16 +<li>postgresql</li> 1.17 +<li>build-essential</li> 1.18 +<li>libpq-dev</li> 1.19 +<li>liblua5.1-0-dev</li> 1.20 +<li>lighttpd</li> 1.21 +<li>ghc</li> 1.22 +<li>libghc6-parsec3-dev</li> 1.23 +<li>imagemagick</li> 1.24 +<li>exim4</li> 1.25 +</ul> 1.26 +<p>If you're using any other Linux distribution or BSD system, install the necessary software components accordingly.</p> 1.27 +<h2 id="ensure-that-the-user-account-of-your-webserver-has-access-to-the-database">2. Ensure that the user account of your webserver has access to the database</h2> 1.28 +<p>Whichever useraccount is used by the webserver (usually <code>www-data</code>) needs to have access to your PostgreSQL installation. This is done by executing PostgreSQL's shell command <code>createuser</code> as database superuser (usually <code>pgsql</code>, or <code>postgres</code> for Debian installations):</p> 1.29 +<pre><code>su - postgres 1.30 +createuser 1.31 + 1.32 +Enter name of role to add: www-data 1.33 +Shall the new role be a superuser? (y/n) n 1.34 +Shall the new role be allowed to create databases? (y/n) y 1.35 +Shall the new role be allowed to create more new roles? (y/n) n 1.36 + 1.37 +exit</code></pre> 1.38 +<h2 id="install-and-configure-liquidfeedback-core">3. Install and configure LiquidFeedback-Core</h2> 1.39 +<p>We recommend to create the database with the same user as your webserver (usually <code>www-data</code>) to avoid having to setup database privileges.</p> 1.40 +<p>The example below installs the database as <code>www-data</code> and stores the two executables <code>lf_update</code> and <code>lf_update_issue_order</code> in the directory <code>/opt/liquid_feedback_core/</code>:</p> 1.41 +<pre><code># Download and unpack LiquidFeedback-Core 1.42 +# from http://www.public-software-group.org/pub/projects/liquid_feedback/backend/ 1.43 +make 1.44 +mkdir /opt/liquid_feedback_core 1.45 +cp core.sql lf_update lf_update_issue_order /opt/liquid_feedback_core 1.46 +su - www-data 1.47 +cd /opt/liquid_feedback_core 1.48 +createdb liquid_feedback 1.49 +createlang plpgsql liquid_feedback # command may be omitted, depending on PostgreSQL version 1.50 +psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback</code></pre> 1.51 +<p>A simple configuration may look as follows:</p> 1.52 +<pre><code>psql liquid_feedback 1.53 + 1.54 +INSERT INTO system_setting (member_ttl) VALUES ('1 year'); 1.55 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 hour', 20, 6); 1.56 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 day', 80, 12); 1.57 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 hour', 200, 60); 1.58 +INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 day', 800, 120); 1.59 +INSERT INTO policy (index, name, admission_time, discussion_time, verification_time, voting_time, issue_quorum_num, issue_quorum_den, initiative_quorum_num, initiative_quorum_den) VALUES (1, 'Default policy', '8 days', '15 days', '8 days', '15 days', 10, 100, 10, 100); 1.60 +INSERT INTO unit (name) VALUES ('Our organization'); 1.61 +INSERT INTO area (unit_id, name) VALUES (1, 'Default area'); 1.62 +INSERT INTO allowed_policy (area_id, policy_id, default_policy) VALUES (1, 1, TRUE);</code></pre> 1.63 +<p>If you want to create an admin user with an empty password (CAUTION!), then execute the following SQL statement:</p> 1.64 +<pre><code>INSERT INTO member (login, name, admin, password) VALUES ('admin', 'Administrator', TRUE, '$1$/EMPTY/$NEWt7XJg2efKwPm4vectc1');</code></pre> 1.65 +<p>Exit the <code>psql</code> interface by typing:</p> 1.66 +<pre><code>\q</code></pre> 1.67 +<p>And don't forget to quit the <code>www-data</code> shell:</p> 1.68 +<pre><code>exit</code></pre> 1.69 +<h2 id="install-webmcp">4. Install WebMCP</h2> 1.70 +<p>Note: Using Debian, it may be necessary to append <code>-I /usr/include/lua5.1</code> at the end of the CFLAGS line in <code>Makefile.options</code> of the WebMCP source distibution:</p> 1.71 +<pre><code># Download and unpack WebMCP 1.72 +# from http://www.public-software-group.org/pub/projects/webmcp/ 1.73 +vi Makefile.options # Debian requires -I /usr/include/lua5.1 at end of CFLAGS line 1.74 +make 1.75 +mkdir /opt/webmcp 1.76 +cp -RL framework/* /opt/webmcp/</code></pre> 1.77 +<h2 id="install-rocketwiki-lqfb-edition">5. Install RocketWiki LqFb-Edition</h2> 1.78 +<pre><code># Download and unpack "RocketWiki LqFb-Edition" 1.79 +# from http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/ 1.80 +make 1.81 +mkdir /opt/rocketwiki-lqfb 1.82 +cp rocketwiki-lqfb rocketwiki-lqfb-compat /opt/rocketwiki-lqfb/</code></pre> 1.83 +<p>If you experience problems with multi-byte encoding (UTF-8) later, then apply the following patch to both <code>rocketwiki-lqfb.hs</code> and <code>rocketwiki-lqfb-compat.hs</code> prior compilation:</p> 1.84 +<pre><code>--- rocketwiki-lqfb.hs 1.85 ++++ rocketwiki-lqfb.hs 1.86 +@@ -1,4 +1,6 @@ 1.87 + 1.88 ++import System.IO (hSetEncoding, stdin, stdout, utf8) 1.89 ++ 1.90 + import Text.ParserCombinators.Parsec 1.91 + import Control.Applicative ((<$>), (<*>)) 1.92 + import Data.List (intercalate) 1.93 +@@ -405,7 +407,10 @@ 1.94 + return htmlEntity 1.95 + 1.96 + 1.97 +-main = interact wikiParse 1.98 ++main = do 1.99 ++ hSetEncoding stdin utf8 1.100 ++ hSetEncoding stdout utf8 1.101 ++ interact wikiParse 1.102 + 1.103 + wikiParse str 1.104 + | success parseResult = html</code></pre> 1.105 +<h2 id="install-the-liquidfeedback-frontend">6. Install the LiquidFeedback-Frontend</h2> 1.106 +<p>Unpack source tree into appropriate directory, e.g. <code>/opt/liquid_feedback_frontend</code>:</p> 1.107 +<pre><code># Download LiquidFeedback-Frontend 1.108 +# from http://www.public-software-group.org/pub/projects/liquid_feedback/frontend/ 1.109 +mv liquid_feedback_frontend-vX.X.X /opt/liquid_feedback_frontend</code></pre> 1.110 +<p>Create HTML code for help texts:</p> 1.111 +<pre><code>cd /opt/liquid_feedback_frontend/locale 1.112 +PATH=/opt/rocketwiki-lqfb:$PATH make</code></pre> 1.113 +<p>Make <code>tmp/</code> directory of LiquidFeedback-Frontend writable for webserver:</p> 1.114 +<pre><code>chown www-data /opt/liquid_feedback_frontend/tmp</code></pre> 1.115 +<p>Compile binary for fast delivery of member images:</p> 1.116 +<pre><code>cd /opt/liquid_feedback_frontend/fastpath 1.117 +vi getpic.c # check and modify #define commands as necessary 1.118 +make</code></pre> 1.119 +<h2 id="configure-mail-system">7. Configure mail system</h2> 1.120 +<p>It may be necessary to configure your server's mail system, e.g. running <code>dpkg-reconfigure exim4-config</code> on a Debian system.</p> 1.121 +<h2 id="configure-the-webserver-for-liquidfeedback">8. Configure the Webserver for LiquidFeedback:</h2> 1.122 +<p>A sample configuration for <code>lighttpd</code> is given below (assuming <code>mod_alias</code> has been included elsewhere):</p> 1.123 +<pre><code>server.modules += ("mod_cgi", "mod_rewrite", "mod_redirect", "mod_setenv") 1.124 + 1.125 +# Enable CGI-Execution of *.lua files through lua binary 1.126 +cgi.assign += ( ".lua" => "/usr/bin/lua5.1" ) 1.127 + 1.128 +alias.url += ( "/lf/fastpath/" => "/opt/liquid_feedback_frontend/fastpath/", 1.129 + "/lf/static" => "/opt/liquid_feedback_frontend/static", 1.130 + "/lf" => "/opt/webmcp/cgi-bin" ) 1.131 + 1.132 +# Configure environment for demo application 1.133 +$HTTP["url"] =~ "^/lf" { 1.134 + setenv.add-environment += ( 1.135 + "LANG" => "en_US.UTF-8", 1.136 + "WEBMCP_APP_BASEPATH" => "/opt/liquid_feedback_frontend/", 1.137 + "WEBMCP_CONFIG_NAME" => "myconfig") 1.138 +} 1.139 + 1.140 +# URL beautification 1.141 +url.rewrite-once += ( 1.142 + # do not rewrite static URLs 1.143 + "^/lf/fastpath/(.*)$" => "/lf/fastpath/$1", 1.144 + "^/lf/static/(.*)$" => "/lf/static/$1", 1.145 + 1.146 + # dynamic URLs 1.147 + "^/lf/([^\?]*)(\?(.*))?$" => "/lf/webmcp-wrapper.lua?_webmcp_path=$1&$3", 1.148 + 1.149 +) 1.150 + 1.151 +$HTTP["url"] =~ "^/lf/fastpath/" { 1.152 + cgi.assign = ( "" => "" ) 1.153 + setenv.add-response-header = ( "Cache-Control" => "private; max-age=86400" ) 1.154 +}</code></pre> 1.155 +<p>If you're using Debian, you may want to create a file with the name <code>/etc/lighttpd/conf-available/60-liquidfeedback.conf</code> and create a softlink in <code>/etc/lighttpd/conf-enabled/</code>.</p> 1.156 +<h2 id="configure-the-liquidfeedback-frontend">9. Configure the LiquidFeedback-Frontend:</h2> 1.157 +<pre><code>cd /opt/liquid_feedback_frontend/config 1.158 +cp example.lua myconfig.lua 1.159 +# edit myconfig.lua according to your needs</code></pre> 1.160 +<p>Use the following option in your configuration file to enable fast image loading:</p> 1.161 +<pre><code>config.fastpath_url_func = function(member_id, image_type) 1.162 + return request.get_absolute_baseurl() .. "fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type) 1.163 +end</code></pre> 1.164 +<h2 id="setup-regular-execution-of-lf_update-and-lf_update_suggestion_order">10. Setup regular execution of <code>lf_update</code> and <code>lf_update_suggestion_order</code></h2> 1.165 +<p>The executables <code>lf_update</code> and <code>lf_update_suggestion_order</code> must be executed regularly. This may be achieved by creating a file named <code>/opt/liquid_feedback_core/lf_updated</code> with the following contents:</p> 1.166 +<pre><code>#!/bin/sh 1.167 + 1.168 +PIDFILE="/var/run/lf_updated.pid" 1.169 +PID=$$ 1.170 + 1.171 +if [ -f "${PIDFILE}" ] && kill -CONT $( cat "${PIDFILE}" ); then 1.172 + echo "lf_updated is already running." 1.173 + exit 1 1.174 +fi 1.175 + 1.176 +echo "${PID}" > "${PIDFILE}" 1.177 + 1.178 +while true; do 1.179 + su - www-data -c 'nice /opt/liquid_feedback_core/lf_update dbname=liquid_feedback 2>&1 | logger -t "lf_updated"' 1.180 + su - www-data -c 'nice /opt/liquid_feedback_core/lf_update_suggestion_order dbname=liquid_feedback 2>&1 | logger -t "lf_updated"' 1.181 + sleep 5 1.182 +done</code></pre> 1.183 +<p>This file must be marked as executable:</p> 1.184 +<pre><code>chmod +x /opt/liquid_feedback_core/lf_updated</code></pre> 1.185 +<p>And this file should be started automatically at system boot.</p> 1.186 +<h2 id="setup-notification-loop-in-background">11. Setup notification loop in background</h2> 1.187 +<p>In addition to regular execution of <code>lf_update</code> and <code>lf_update_suggestion_order</code>, the following commands should be executed in background:</p> 1.188 +<pre><code>su - www-data 1.189 +cd /opt/liquid_feedback_frontend/ 1.190 +echo "Event:send_notifications_loop()" | ../webmcp/bin/webmcp_shell myconfig</code></pre> 1.191 +<h2 id="start-the-sytem">12. Start the sytem</h2> 1.192 +<p>After <code>lf_update</code> has been executed at least once, and the webserver has been restarted (using the configuration above), you should be able to access your LiquidFeedback system.</p> 1.193 +</body> 1.194 +</html>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/INSTALL.mkd Thu Jul 10 01:19:48 2014 +0200 2.3 @@ -0,0 +1,289 @@ 2.4 +LiquidFeedback Installation Instructions 2.5 +======================================== 2.6 + 2.7 +This document gives a short outline about the necessary steps to setup a 2.8 +LiquidFeedback system. 2.9 + 2.10 + 2.11 +1. Install necessary dependencies 2.12 +--------------------------------- 2.13 + 2.14 +If you're using a Debian system, make sure that the following packages are 2.15 +installed: 2.16 + 2.17 + * lua5.1 2.18 + * postgresql 2.19 + * build-essential 2.20 + * libpq-dev 2.21 + * liblua5.1-0-dev 2.22 + * lighttpd 2.23 + * ghc 2.24 + * libghc6-parsec3-dev 2.25 + * imagemagick 2.26 + * exim4 2.27 + 2.28 +If you're using any other Linux distribution or BSD system, install the 2.29 +necessary software components accordingly. 2.30 + 2.31 + 2.32 +2. Ensure that the user account of your webserver has access to the database 2.33 +---------------------------------------------------------------------------- 2.34 + 2.35 +Whichever useraccount is used by the webserver (usually `www-data`) needs to 2.36 +have access to your PostgreSQL installation. This is done by executing 2.37 +PostgreSQL's shell command `createuser` as database superuser (usually `pgsql`, 2.38 +or `postgres` for Debian installations): 2.39 + 2.40 + su - postgres 2.41 + createuser 2.42 + 2.43 + Enter name of role to add: www-data 2.44 + Shall the new role be a superuser? (y/n) n 2.45 + Shall the new role be allowed to create databases? (y/n) y 2.46 + Shall the new role be allowed to create more new roles? (y/n) n 2.47 + 2.48 + exit 2.49 + 2.50 + 2.51 +3. Install and configure LiquidFeedback-Core 2.52 +-------------------------------------------- 2.53 + 2.54 +We recommend to create the database with the same user as your webserver 2.55 +(usually `www-data`) to avoid having to setup database privileges. 2.56 + 2.57 +The example below installs the database as `www-data` and stores the two 2.58 +executables `lf_update` and `lf_update_issue_order` in the directory 2.59 +`/opt/liquid_feedback_core/`: 2.60 + 2.61 + # Download and unpack LiquidFeedback-Core 2.62 + # from http://www.public-software-group.org/pub/projects/liquid_feedback/backend/ 2.63 + make 2.64 + mkdir /opt/liquid_feedback_core 2.65 + cp core.sql lf_update lf_update_issue_order /opt/liquid_feedback_core 2.66 + su - www-data 2.67 + cd /opt/liquid_feedback_core 2.68 + createdb liquid_feedback 2.69 + createlang plpgsql liquid_feedback # command may be omitted, depending on PostgreSQL version 2.70 + psql -v ON_ERROR_STOP=1 -f core.sql liquid_feedback 2.71 + 2.72 +A simple configuration may look as follows: 2.73 + 2.74 + psql liquid_feedback 2.75 + 2.76 + INSERT INTO system_setting (member_ttl) VALUES ('1 year'); 2.77 + INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 hour', 20, 6); 2.78 + INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (false, '1 day', 80, 12); 2.79 + INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 hour', 200, 60); 2.80 + INSERT INTO contingent (polling, time_frame, text_entry_limit, initiative_limit) VALUES (true, '1 day', 800, 120); 2.81 + INSERT INTO policy (index, name, admission_time, discussion_time, verification_time, voting_time, issue_quorum_num, issue_quorum_den, initiative_quorum_num, initiative_quorum_den) VALUES (1, 'Default policy', '8 days', '15 days', '8 days', '15 days', 10, 100, 10, 100); 2.82 + INSERT INTO unit (name) VALUES ('Our organization'); 2.83 + INSERT INTO area (unit_id, name) VALUES (1, 'Default area'); 2.84 + INSERT INTO allowed_policy (area_id, policy_id, default_policy) VALUES (1, 1, TRUE); 2.85 + 2.86 +If you want to create an admin user with an empty password (CAUTION!), then execute the following SQL statement: 2.87 + 2.88 + INSERT INTO member (login, name, admin, password) VALUES ('admin', 'Administrator', TRUE, '$1$/EMPTY/$NEWt7XJg2efKwPm4vectc1'); 2.89 + 2.90 +Exit the `psql` interface by typing: 2.91 + 2.92 + \q 2.93 + 2.94 +And don't forget to quit the `www-data` shell: 2.95 + 2.96 + exit 2.97 + 2.98 + 2.99 +4. Install WebMCP 2.100 +----------------- 2.101 + 2.102 +Note: Using Debian, it may be necessary to append `-I /usr/include/lua5.1` at 2.103 +the end of the CFLAGS line in `Makefile.options` of the WebMCP source 2.104 +distibution: 2.105 + 2.106 + # Download and unpack WebMCP 2.107 + # from http://www.public-software-group.org/pub/projects/webmcp/ 2.108 + vi Makefile.options # Debian requires -I /usr/include/lua5.1 at end of CFLAGS line 2.109 + make 2.110 + mkdir /opt/webmcp 2.111 + cp -RL framework/* /opt/webmcp/ 2.112 + 2.113 + 2.114 +5. Install RocketWiki LqFb-Edition 2.115 +---------------------------------- 2.116 + 2.117 + # Download and unpack "RocketWiki LqFb-Edition" 2.118 + # from http://www.public-software-group.org/pub/projects/rocketwiki/liquid_feedback_edition/ 2.119 + make 2.120 + mkdir /opt/rocketwiki-lqfb 2.121 + cp rocketwiki-lqfb rocketwiki-lqfb-compat /opt/rocketwiki-lqfb/ 2.122 + 2.123 +If you experience problems with multi-byte encoding (UTF-8) later, then apply 2.124 +the following patch to both `rocketwiki-lqfb.hs` and 2.125 +`rocketwiki-lqfb-compat.hs` prior compilation: 2.126 + 2.127 + --- rocketwiki-lqfb.hs 2.128 + +++ rocketwiki-lqfb.hs 2.129 + @@ -1,4 +1,6 @@ 2.130 + 2.131 + +import System.IO (hSetEncoding, stdin, stdout, utf8) 2.132 + + 2.133 + import Text.ParserCombinators.Parsec 2.134 + import Control.Applicative ((<$>), (<*>)) 2.135 + import Data.List (intercalate) 2.136 + @@ -405,7 +407,10 @@ 2.137 + return htmlEntity 2.138 + 2.139 + 2.140 + -main = interact wikiParse 2.141 + +main = do 2.142 + + hSetEncoding stdin utf8 2.143 + + hSetEncoding stdout utf8 2.144 + + interact wikiParse 2.145 + 2.146 + wikiParse str 2.147 + | success parseResult = html 2.148 + 2.149 + 2.150 +6. Install the LiquidFeedback-Frontend 2.151 +-------------------------------------- 2.152 + 2.153 +Unpack source tree into appropriate directory, e.g. `/opt/liquid_feedback_frontend`: 2.154 + 2.155 + # Download LiquidFeedback-Frontend 2.156 + # from http://www.public-software-group.org/pub/projects/liquid_feedback/frontend/ 2.157 + mv liquid_feedback_frontend-vX.X.X /opt/liquid_feedback_frontend 2.158 + 2.159 +Create HTML code for help texts: 2.160 + 2.161 + cd /opt/liquid_feedback_frontend/locale 2.162 + PATH=/opt/rocketwiki-lqfb:$PATH make 2.163 + 2.164 +Make `tmp/` directory of LiquidFeedback-Frontend writable for webserver: 2.165 + 2.166 + chown www-data /opt/liquid_feedback_frontend/tmp 2.167 + 2.168 +Compile binary for fast delivery of member images: 2.169 + 2.170 + cd /opt/liquid_feedback_frontend/fastpath 2.171 + vi getpic.c # check and modify #define commands as necessary 2.172 + make 2.173 + 2.174 + 2.175 +7. Configure mail system 2.176 +------------------------ 2.177 + 2.178 +It may be necessary to configure your server's mail system, e.g. running 2.179 +`dpkg-reconfigure exim4-config` on a Debian system. 2.180 + 2.181 + 2.182 +8. Configure the Webserver for LiquidFeedback: 2.183 +---------------------------------------------- 2.184 + 2.185 +A sample configuration for `lighttpd` is given below (assuming `mod_alias` has 2.186 +been included elsewhere): 2.187 + 2.188 + server.modules += ("mod_cgi", "mod_rewrite", "mod_redirect", "mod_setenv") 2.189 + 2.190 + # Enable CGI-Execution of *.lua files through lua binary 2.191 + cgi.assign += ( ".lua" => "/usr/bin/lua5.1" ) 2.192 + 2.193 + alias.url += ( "/lf/fastpath/" => "/opt/liquid_feedback_frontend/fastpath/", 2.194 + "/lf/static" => "/opt/liquid_feedback_frontend/static", 2.195 + "/lf" => "/opt/webmcp/cgi-bin" ) 2.196 + 2.197 + # Configure environment for demo application 2.198 + $HTTP["url"] =~ "^/lf" { 2.199 + setenv.add-environment += ( 2.200 + "LANG" => "en_US.UTF-8", 2.201 + "WEBMCP_APP_BASEPATH" => "/opt/liquid_feedback_frontend/", 2.202 + "WEBMCP_CONFIG_NAME" => "myconfig") 2.203 + } 2.204 + 2.205 + # URL beautification 2.206 + url.rewrite-once += ( 2.207 + # do not rewrite static URLs 2.208 + "^/lf/fastpath/(.*)$" => "/lf/fastpath/$1", 2.209 + "^/lf/static/(.*)$" => "/lf/static/$1", 2.210 + 2.211 + # dynamic URLs 2.212 + "^/lf/([^\?]*)(\?(.*))?$" => "/lf/webmcp-wrapper.lua?_webmcp_path=$1&$3", 2.213 + 2.214 + ) 2.215 + 2.216 + $HTTP["url"] =~ "^/lf/fastpath/" { 2.217 + cgi.assign = ( "" => "" ) 2.218 + setenv.add-response-header = ( "Cache-Control" => "private; max-age=86400" ) 2.219 + } 2.220 + 2.221 +If you're using Debian, you may want to create a file with the name 2.222 +`/etc/lighttpd/conf-available/60-liquidfeedback.conf` and create a softlink in 2.223 +`/etc/lighttpd/conf-enabled/`. 2.224 + 2.225 + 2.226 +9. Configure the LiquidFeedback-Frontend: 2.227 +----------------------------------------- 2.228 + 2.229 + cd /opt/liquid_feedback_frontend/config 2.230 + cp example.lua myconfig.lua 2.231 + # edit myconfig.lua according to your needs 2.232 + 2.233 +Use the following option in your configuration file to enable fast image 2.234 +loading: 2.235 + 2.236 + config.fastpath_url_func = function(member_id, image_type) 2.237 + return request.get_absolute_baseurl() .. "fastpath/getpic?" .. tostring(member_id) .. "+" .. tostring(image_type) 2.238 + end 2.239 + 2.240 + 2.241 +10. Setup regular execution of `lf_update` and `lf_update_suggestion_order` 2.242 +--------------------------------------------------------------------------- 2.243 + 2.244 +The executables `lf_update` and `lf_update_suggestion_order` must be executed 2.245 +regularly. This may be achieved by creating a file named 2.246 +`/opt/liquid_feedback_core/lf_updated` with the following contents: 2.247 + 2.248 + #!/bin/sh 2.249 + 2.250 + PIDFILE="/var/run/lf_updated.pid" 2.251 + PID=$$ 2.252 + 2.253 + if [ -f "${PIDFILE}" ] && kill -CONT $( cat "${PIDFILE}" ); then 2.254 + echo "lf_updated is already running." 2.255 + exit 1 2.256 + fi 2.257 + 2.258 + echo "${PID}" > "${PIDFILE}" 2.259 + 2.260 + while true; do 2.261 + su - www-data -c 'nice /opt/liquid_feedback_core/lf_update dbname=liquid_feedback 2>&1 | logger -t "lf_updated"' 2.262 + su - www-data -c 'nice /opt/liquid_feedback_core/lf_update_suggestion_order dbname=liquid_feedback 2>&1 | logger -t "lf_updated"' 2.263 + sleep 5 2.264 + done 2.265 + 2.266 +This file must be marked as executable: 2.267 + 2.268 + chmod +x /opt/liquid_feedback_core/lf_updated 2.269 + 2.270 +And this file should be started automatically at system boot. 2.271 + 2.272 + 2.273 +11. Setup notification loop in background 2.274 +----------------------------------------- 2.275 + 2.276 +In addition to regular execution of `lf_update` and 2.277 +`lf_update_suggestion_order`, the following commands should be executed in 2.278 +background: 2.279 + 2.280 + su - www-data 2.281 + cd /opt/liquid_feedback_frontend/ 2.282 + echo "Event:send_notifications_loop()" | ../webmcp/bin/webmcp_shell myconfig 2.283 + 2.284 + 2.285 +12. Start the sytem 2.286 +------------------- 2.287 + 2.288 +After `lf_update` has been executed at least once, and the webserver has been 2.289 +restarted (using the configuration above), you should be able to access your 2.290 +LiquidFeedback system. 2.291 + 2.292 +
3.1 --- a/LICENSE Thu Jul 10 01:02:43 2014 +0200 3.2 +++ b/LICENSE Thu Jul 10 01:19:48 2014 +0200 3.3 @@ -1,4 +1,4 @@ 3.4 -Copyright (c) 2009-2013 Public Software Group e. V., Berlin, Germany 3.5 +Copyright (c) 2009-2014 Public Software Group e. V., Berlin, Germany 3.6 3.7 Permission is hereby granted, free of charge, to any person obtaining a 3.8 copy of this software and associated documentation files (the "Software"),
4.1 --- a/app/main/_filter/21_auth.lua Thu Jul 10 01:02:43 2014 +0200 4.2 +++ b/app/main/_filter/21_auth.lua Thu Jul 10 01:19:48 2014 +0200 4.3 @@ -5,8 +5,7 @@ 4.4 local auth_needed = not ( 4.5 module == 'index' 4.6 and ( 4.7 - view == "index" 4.8 - or view == "login" 4.9 +view == "login" 4.10 or action == "login" 4.11 or view == "register" 4.12 or action == "register" 4.13 @@ -26,16 +25,17 @@ 4.14 if app.session:has_access("anonymous") then 4.15 4.16 if 4.17 - module == "area" and view == "show" 4.18 + module == "index" and view == "index" 4.19 + or module == "area" and view == "show" 4.20 or module == "unit" and view == "show" 4.21 or module == "policy" and view == "show" 4.22 or module == "policy" and view == "list" 4.23 or module == "issue" and view == "show" 4.24 or module == "initiative" and view == "show" 4.25 + or module == "initiative" and view == "history" 4.26 or module == "suggestion" and view == "show" 4.27 or module == "draft" and view == "diff" 4.28 or module == "draft" and view == "show" 4.29 - or module == "draft" and view == "list" 4.30 or module == "index" and view == "search" 4.31 or module == "index" and view == "usage_terms" 4.32 then 4.33 @@ -44,11 +44,16 @@ 4.34 4.35 end 4.36 4.37 +if app.session:has_access("authors_pseudonymous") then 4.38 + if module == "member_image" and view == "show" then 4.39 + auth_needed = false 4.40 + end 4.41 +end 4.42 + 4.43 if app.session:has_access("all_pseudonymous") then 4.44 - if module == "member_image" and view == "show" 4.45 - or module == "vote" and view == "show_incoming" 4.46 + if module == "vote" and view == "show_incoming" 4.47 + or module == "member" and view == "list" 4.48 or module == "interest" and view == "show_incoming" 4.49 - or module == "supporter" and view == "show_incoming" 4.50 or module == "vote" and view == "list" then 4.51 auth_needed = false 4.52 end
5.1 --- a/app/main/_filter_view/30_navigation.lua Thu Jul 10 01:02:43 2014 +0200 5.2 +++ b/app/main/_filter_view/30_navigation.lua Thu Jul 10 01:19:48 2014 +0200 5.3 @@ -1,88 +1,86 @@ 5.4 -slot.select('navigation', function() 5.5 +slot.select ( 'instance_name', function () 5.6 + slot.put ( encode.html ( config.instance_name ) ) 5.7 +end) 5.8 5.9 - ui.link{ 5.10 - content = function() 5.11 - ui.tag{ attr = { class = "logo_liquidfeedback" }, content = _"LiquidFeedback" } 5.12 - slot.put(" · ") 5.13 - ui.tag{ content = config.instance_name } 5.14 - end, 5.15 - module = 'index', 5.16 - view = 'index' 5.17 - } 5.18 5.19 - if app.session:has_access("anonymous") and not (app.session.needs_delegation_check) then 5.20 +slot.select ( 'navigation_right', function () 5.21 5.22 - ui.link{ 5.23 - content = _"Search", 5.24 - module = 'index', 5.25 - view = 'search' 5.26 - } 5.27 + if app.session:has_access ("anonymous") and not (app.session.needs_delegation_check) then 5.28 5.29 - if app.session.member == nil then 5.30 - ui.link{ 5.31 - text = _"Login", 5.32 - module = 'index', 5.33 - view = 'login', 5.34 - params = { 5.35 - redirect_module = request.get_module(), 5.36 - redirect_view = request.get_view(), 5.37 - redirect_id = param.get_id() 5.38 + ui.form { 5.39 + attr = { class = "inline search" }, 5.40 + method = "get", 5.41 + module = "index", view = "search", 5.42 + content = function () 5.43 + 5.44 + ui.field.text { 5.45 + attr = { placeholder = "search" }, 5.46 + name = "q" 5.47 } 5.48 - } 5.49 - end 5.50 + 5.51 + end 5.52 + } 5.53 + 5.54 + ui.link { 5.55 + attr = { class = "searchLink" }, 5.56 + module = "index", view = "search", content = function () 5.57 + ui.image { static = "icons/16/magnifier.png" } 5.58 + end 5.59 + } 5.60 5.61 end 5.62 - 5.63 + 5.64 if app.session.member == nil then 5.65 - ui.link{ 5.66 + 5.67 + slot.put ( " " ) 5.68 + 5.69 + ui.link { 5.70 + text = _"Login", 5.71 + module = 'index', 5.72 + view = 'login', 5.73 + params = { 5.74 + redirect_module = request.get_module(), 5.75 + redirect_view = request.get_view(), 5.76 + redirect_id = param.get_id() 5.77 + } 5.78 + } 5.79 + 5.80 + slot.put ( " " ) 5.81 + 5.82 + ui.link { 5.83 text = _"Registration", 5.84 module = 'index', 5.85 view = 'register' 5.86 } 5.87 + 5.88 end 5.89 + 5.90 + 5.91 + if app.session.member then 5.92 + 5.93 + slot.put ( " " ) 5.94 + 5.95 + ui.tag { attr = { id = "member_menu" }, content = function() 5.96 + util.micro_avatar(app.session.member) 5.97 + end } 5.98 + 5.99 + end -- if app.session.member 5.100 + 5.101 end) 5.102 5.103 +-- show notifications about things the user should take care of 5.104 +if app.session.member then 5.105 + execute.view{ 5.106 + module = "index", view = "_sidebar_notifications", params = { 5.107 + mode = "link" 5.108 + } 5.109 + } 5.110 +end 5.111 5.112 -slot.select('navigation_right', function() 5.113 - ui.tag{ 5.114 - tag = "ul", 5.115 - attr = { id = "member_menu" }, 5.116 - content = function() 5.117 - ui.tag{ 5.118 - tag = "li", 5.119 - content = function() 5.120 - ui.link{ 5.121 - module = "index", 5.122 - view = "menu", 5.123 - content = function() 5.124 - if app.session.member_id then 5.125 - execute.view{ 5.126 - module = "member_image", 5.127 - view = "_show", 5.128 - params = { 5.129 - member = app.session.member, 5.130 - image_type = "avatar", 5.131 - show_dummy = true, 5.132 - class = "micro_avatar", 5.133 - } 5.134 - } 5.135 - ui.tag{ content = app.session.member.name } 5.136 - else 5.137 - ui.tag{ content = _"Select language" } 5.138 - end 5.139 - end 5.140 - } 5.141 - execute.view{ module = "index", view = "_menu" } 5.142 - end 5.143 - } 5.144 - end 5.145 - } 5.146 -end) 5.147 - 5.148 -slot.select("footer", function() 5.149 +slot.select ("footer", function () 5.150 if app.session.member_id and app.session.member.admin then 5.151 - ui.link{ 5.152 - text = _"Admin", 5.153 + ui.link { 5.154 + text = _"System settings", 5.155 module = 'admin', 5.156 view = 'index' 5.157 } 5.158 @@ -102,8 +100,6 @@ 5.159 } 5.160 end 5.161 slot.put(" · ") 5.162 - ui.tag{ content = _"This site is using" } 5.163 - slot.put(" ") 5.164 ui.link{ 5.165 text = _"LiquidFeedback", 5.166 external = "http://www.public-software-group.org/liquid_feedback"
6.1 --- a/app/main/_layout/default.html Thu Jul 10 01:02:43 2014 +0200 6.2 +++ b/app/main/_layout/default.html Thu Jul 10 01:19:48 2014 +0200 6.3 @@ -1,67 +1,277 @@ 6.4 <html> 6.5 - <head> 6.6 - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 6.7 - <meta name="viewport" content="width=device-width" /> 6.8 - <title> <!-- WEBMCP SLOTNODIV html_title --></title> 6.9 - <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" /> 6.10 - <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" /> 6.11 - <link rel="stylesheet" type="text/css" media="screen" href="<!-- WEBMCP SLOTNODIV stylesheet_url -->" /> 6.12 - <!-- WEBMCP SLOTNODIV html_head --> 6.13 - <script type="text/javascript">jsFail = true;</script> 6.14 - <![if !IE]> 6.15 - <script type="text/javascript">jsFail = false;</script> 6.16 - <![endif]> 6.17 - <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script> 6.18 - <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script> 6.19 - <script type="text/javascript">var ui_tabs_active = {};</script> 6.20 - </head> 6.21 - <body> 6.22 - <div class="topbar"> 6.23 - <div class="topbar_content"> 6.24 - <div class="navigation" id="navigation"> 6.25 - <!-- WEBMCP SLOT navigation --> 6.26 - </div> 6.27 - <div class="navigation_right" id="navigation_right"> 6.28 - <!-- WEBMCP SLOT navigation_right --> 6.29 - </div> 6.30 - <div class="help_hidden" id="help_hidden"> 6.31 - <!-- WEBMCP SLOT help_hidden --> 6.32 - </div> 6.33 - <br style="clear: both;" /> 6.34 +<head> 6.35 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 6.36 + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> 6.37 + <title><!-- WEBMCP SLOTNODIV html_title --></title> 6.38 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" /> 6.39 + <link rel="stylesheet" type="text/less" href="__BASEURL__/static/lf3.less" /> 6.40 + <!-- WEBMCP SLOTNODIV html_head --> 6.41 + <script type="text/javascript" src="__BASEURL__/static/js/less-1.4.1.min.js"></script> 6.42 + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 6.43 + <script type="text/javascript">jsFail = true;</script> 6.44 + <![if !IE]> 6.45 + <script type="text/javascript">jsFail = false;</script> 6.46 + <![endif]> 6.47 + <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script> 6.48 + <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script> 6.49 + <script type="text/javascript">var ui_tabs_active = {};</script> 6.50 +</head> 6.51 +<body style=""> 6.52 +<div class="head_outer"> 6.53 + <div class="head"> 6.54 + <div class="nav"> 6.55 + <!--WEBMCP SLOTNODIV navigation --> 6.56 + <!--WEBMCP SLOTNODIV navigation_right --> 6.57 + <!--WEBMCP SLOTNODIV notification --> 6.58 + </div> 6.59 + 6.60 + <a class="logo" href="__BASEURL__/"> 6.61 + <span class="liquid">Liquid</span><span class="feedback">Feedback</span> 6.62 + <span class="instanceName"><!-- WEBMCP SLOTNODIV instance_name --></span> 6.63 + </a> 6.64 + 6.65 + 6.66 + </div> 6.67 +</div> 6.68 + 6.69 +<div class="page"> 6.70 + <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';"> 6.71 + <!-- WEBMCP SLOT notice --> 6.72 + </div> 6.73 + 6.74 + <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';"> 6.75 + <!-- WEBMCP SLOT warning --> 6.76 + </div> 6.77 + 6.78 + <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';"> 6.79 + <!-- WEBMCP SLOT error --> 6.80 + </div> 6.81 + 6.82 + <div class="layout_motd" id="layout_motd" onclick="document.getElementById('layout_motd').style.display='none';"> 6.83 + <!-- WEBMCP SLOT motd --> 6.84 + </div> 6.85 + 6.86 + <div class="title_outer"> 6.87 + <!-- WEBMCP SLOT title --> 6.88 + </div> 6.89 + 6.90 + <!-- WEBMCP SLOT tabs --> 6.91 + 6.92 + <!-- WEBMCP SLOTNODIV actions --> 6.93 + 6.94 + <div id="swiper_tabs" class="swiper_tabs" style="display: none;"> 6.95 +<!-- <div><a id="tab-0" href="#" onclick="slider.to(0); return false;"><img src="__BASEURL__/static/icons/16/chart_organisation.png" /></a></div>--> 6.96 + <div><a id="tab-0" href="#" onclick="slider.to(0); return false;"><img src="__BASEURL__/static/icons/16/text_list_bullets.png" width="32" height="32" /></a></div> 6.97 + <div><a id="tab-1" href="#" onclick="slider.to(1); return false;"><img src="__BASEURL__/static/icons/48/info.png" width="32" height="32" /></a></div> 6.98 + <div><a id="tab-2" href="#" onclick="slider.to(2); return false;"><img src="__BASEURL__/static/icons/16/group.png" width="32" height="32" /></a></div> 6.99 + </div> 6.100 + 6.101 + <div id="swiper_info"><!-- WEBMCP SLOTNODIV swiper_info --></div> 6.102 + <div id="swiper" class="swiper" style="position: absolute; width: 100%;"> 6.103 + <div id="swiper_wrap" class="swiper_wrap"> 6.104 + </div> 6.105 + </div> 6.106 + 6.107 + <div class="content"> 6.108 + <div class="sidebar"> 6.109 + <!-- WEBMCP SLOTNODIV sidebar --> 6.110 + </div> 6.111 + 6.112 + <div class="main_outer"> 6.113 + <!-- WEBMCP SLOTNODIV slideshow --> 6.114 + <div class="main"> 6.115 + <!-- WEBMCP SLOTNODIV default --> 6.116 + <!-- WEBMCP SLOTNODIV extra --> 6.117 </div> 6.118 </div> 6.119 - <div class="page"> 6.120 - <div class="page_head" id="head"> 6.121 - <!-- WEBMCP SLOT head --> 6.122 - </div> 6.123 - <div class="layout_notice" id="layout_notice" onclick="document.getElementById('layout_notice').style.display='none';"> 6.124 - <!-- WEBMCP SLOT notice --> 6.125 - </div> 6.126 - <div class="layout_warning" id="layout_warning" onclick="document.getElementById('layout_warning').style.display='none';"> 6.127 - <!-- WEBMCP SLOT warning --> 6.128 - </div> 6.129 - <div class="layout_error" id="layout_error" onclick="document.getElementById('layout_error').style.display='none';"> 6.130 - <!-- WEBMCP SLOT error --> 6.131 - </div> 6.132 - <div class="main" id="default"> 6.133 - <!-- WEBMCP SLOT default --> 6.134 - </div> 6.135 - <br style="clear: both;" /> 6.136 - </div> 6.137 - <div class="footer" id="footer"> 6.138 - <!-- WEBMCP SLOT footer --> 6.139 - </div> 6.140 - <!-- WEBMCP SLOT trace_button --> 6.141 + </div> 6.142 + <br style="clear: both;" /> 6.143 + <div class="footer"> 6.144 + <!-- WEBMCP SLOTNODIV footer --> 6.145 + </div> 6.146 +</div> 6.147 + 6.148 + <div id="trace"> 6.149 + <!-- WEBMCP SLOTNODIV trace_button --> 6.150 <div id="trace_content" style="display: none;"> 6.151 <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt> 6.152 - <div id="trace"> </div><hr /> 6.153 + <h1>System trace (for computer programmers purposes)</h1> 6.154 + <br /> 6.155 <!-- WEBMCP SLOT trace --> 6.156 <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';"> 6.157 close 6.158 </div> 6.159 </div> 6.160 - <script type="text/javascript"> 6.161 - <!-- WEBMCP SLOTNODIV custom_script --> 6.162 - </script> 6.163 - </body> 6.164 + </div> 6.165 + <script> 6.166 + $(".trace_view > .trace_list").hide(); 6.167 + $(".trace_head").click(function() { 6.168 + var el = this.nextSibling 6.169 + if (el) $(el).toggle(); 6.170 + }); 6.171 + </script> 6.172 + 6.173 + <!-- WEBMCP SLOTNODIV script --> 6.174 + 6.175 + <script> 6.176 + 6.177 + var slider; 6.178 + 6.179 + function initSlider () { 6.180 + 6.181 + var els = [ 6.182 + $( '.main, .extra' ), 6.183 + $( '.tab-notification, .tab-whatcanido' ), 6.184 + $( '.tab-members' ) 6.185 + ]; 6.186 + 6.187 + var sidebarFound = false; 6.188 + for ( i = 1; i < els.length; i++) { 6.189 + if (els[i].length > 0) sidebarFound = true; 6.190 + } 6.191 + 6.192 + if (sidebarFound) $("#swiper_tabs").show(); 6.193 + 6.194 + var elsCount = 3; 6.195 + 6.196 + var slidePos; 6.197 + 6.198 + function slideTo ( pos ) { 6.199 + if ( typeof ( slidePos ) != "undefined" ) { 6.200 + els[ slidePos ].hide(); 6.201 + $ ( "#tab-" + slidePos ).removeClass ( "active" ); 6.202 + } 6.203 + slidePos = pos; 6.204 + els[ slidePos ].show(); 6.205 + $ ( "#tab-" + slidePos ).addClass ( "active" ); 6.206 + if (pos == 1) { 6.207 + $("#swiper_info").hide(); 6.208 + } 6.209 + } 6.210 + 6.211 + function slideNext () { 6.212 + var pos = slidePos + 1; 6.213 + if ( pos > elsCount - 1 ) { 6.214 + pos = elsCount - 1; 6.215 + } else { 6.216 + $( "#swiper").css("left", "400px"); 6.217 + $( "#swiper").animate({ "left": "0px" }, 200); 6.218 + } 6.219 + slideTo ( pos ); 6.220 + } 6.221 + 6.222 + function slidePrev () { 6.223 + var pos = slidePos - 1; 6.224 + if ( pos < 0 ) { 6.225 + pos = 0; 6.226 + } else { 6.227 + $( "#swiper").css("left", "-400px"); 6.228 + $( "#swiper").animate({ "left": "0px" }, 200); 6.229 + } 6.230 + slideTo ( pos ); 6.231 + } 6.232 + 6.233 + function exit() { 6.234 + for ( i = 0; i < els.length; i++) { 6.235 + els[i].show(); 6.236 + } 6.237 + $( ".main_outer" ).append ( $( ".main" ).detach() ); 6.238 + $( ".extra_outer" ).append ( $( ".extra" ).detach() ); 6.239 + $( ".sidebar" ).append ( $(els[1]).detach() ); 6.240 + $( ".sidebar" ).append ( $(els[2]).detach() ); 6.241 + $( ".page" ).append ( $('.footer') ); 6.242 + $( "body" ).append ( $('#trace') ); 6.243 + 6.244 + } 6.245 + 6.246 + var touchStartX; 6.247 + var touchStartY; 6.248 + var isScrolling; 6.249 + 6.250 + function touchDown ( e ) { 6.251 + touchStartX = e.originalEvent.touches[0].pageX; 6.252 + touchStartY = e.originalEvent.touches[0].pageY; 6.253 + isScrolling = undefined; 6.254 + } 6.255 + 6.256 + function touchMove ( e ) { 6.257 + var diffX = touchStartX - e.originalEvent.changedTouches[0].pageX; 6.258 + var diffY = touchStartY - e.originalEvent.changedTouches[0].pageY; 6.259 + if ( typeof( isScrolling ) == 'undefined' ) { 6.260 + isScrolling = Math.abs ( diffY ) > Math.abs ( diffX ); 6.261 + } 6.262 + if ( ! isScrolling ) { 6.263 + $( "#swiper").css("left", -diffX + "px"); 6.264 + e.preventDefault(); 6.265 + } 6.266 + } 6.267 + 6.268 + function touchUp ( e ) { 6.269 + var diffX = touchStartX - e.originalEvent.changedTouches[0].pageX; 6.270 + var diffY = touchStartY - e.originalEvent.changedTouches[0].pageY; 6.271 + 6.272 + if ( isScrolling ) { 6.273 + // vertical scrolling 6.274 + return; 6.275 + } 6.276 + 6.277 + if ( Math.abs ( diffX ) < 100 ) { 6.278 + // go back not enough 6.279 + $( "#swiper").animate({ 6.280 + "left": "0px", 6.281 + }, 200); 6.282 + return; 6.283 + } 6.284 + var direction = diffX < 0 ? "right" : "left"; 6.285 + 6.286 + if ( direction == "left" ) { 6.287 + slideNext(); 6.288 + } else { 6.289 + slidePrev(); 6.290 + } 6.291 + } 6.292 + 6.293 + for ( i = 0; i < els.length; i++) { 6.294 + var el = els[i].detach(); 6.295 + el.hide(); 6.296 + $('#swiper_wrap').append ( el ) ; 6.297 + } 6.298 + 6.299 + $('#swiper_wrap').append ( $('.footer') ); 6.300 + $('#swiper_wrap').append ( $('#trace') ); 6.301 + slideTo ( 0 ); 6.302 + 6.303 + if ( 'ontouchstart' in document.documentElement ) { 6.304 + $( "body" ).on( "touchstart", touchDown ); 6.305 + $( "body" ).on( "touchmove", touchMove ); 6.306 + $( "body" ).on( "touchend", touchUp ); 6.307 + } 6.308 + 6.309 + return { 6.310 + to: slideTo, 6.311 + exit: exit 6.312 + } 6.313 + 6.314 + } 6.315 + 6.316 + function resizeHandler() { 6.317 + if ( $(window).width() < 768 ) { 6.318 + if ( typeof ( slider ) == "undefined" ) { 6.319 + slider = initSlider(); 6.320 + } 6.321 + } else { 6.322 + if ( typeof ( slider ) != "undefined" ) { 6.323 + slider.exit(); 6.324 + slider = undefined; 6.325 + } 6.326 + } 6.327 + 6.328 + } 6.329 + 6.330 + $( window ).resize( resizeHandler ); 6.331 + resizeHandler(); 6.332 + 6.333 + </script> 6.334 + 6.335 +</body> 6.336 </html>
7.1 --- a/app/main/_layout/system_error.html Thu Jul 10 01:02:43 2014 +0200 7.2 +++ b/app/main/_layout/system_error.html Thu Jul 10 01:19:48 2014 +0200 7.3 @@ -1,75 +1,86 @@ 7.4 <html> 7.5 - <head> 7.6 - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 7.7 - <title>LiquidFeedback Error</title> 7.8 - <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/trace.css" /> 7.9 - <style> 7.10 - body { 7.11 - font-family: sans-serif; 7.12 - } 7.13 - .title { 7.14 - font-size: 150%; 7.15 - font-weight: bold; 7.16 - } 7.17 - .layout_trace { 7.18 - left: 0; 7.19 - } 7.20 - a { 7.21 - background-color: #ddd; 7.22 - color: #000; 7.23 - padding: 1ex; 7.24 - margin: 1ex; 7.25 - line-height: 300%; 7.26 - border: 1px solid #777; 7.27 - } 7.28 - hr { 7.29 - margin-top: 2ex; 7.30 - margin-bottom: 2ex; 7.31 - } 7.32 - </style> 7.33 - </head> 7.34 - <body class="system_error"> 7.35 - 7.36 - <div class="title"> 7.37 - <img src="__BASEURL__/static/lang/en.png" /> 7.38 - Ooops, a system error occured 7.39 - </div> 7.40 - <p> 7.41 - Most probably you found a software bug. Don't panic, you can now choose one of the following options: 7.42 - </p> 7.43 - 7.44 - <nobr><a href="__BASEURL__">Go to start page</a></nobr> 7.45 - <nobr><a href="#" onclick="window.location.reload()">Retry request</a></nobr> 7.46 - <nobr><a href="http://trac.public-software-group.org/projects/lf" target="_blank">Create bug report</a></nobr> 7.47 - 7.48 - <hr /> 7.49 - 7.50 - <div class="title"> 7.51 - <img src="__BASEURL__/static/lang/de.png" /> 7.52 - Leider ist ein Systemfehler aufgetreten 7.53 - </div> 7.54 - <p> 7.55 - Du hast vermutlich gerade einen Fehler in der Software entdeckt. Das ist kein Grund zur Panik, dir bleiben die folgenden Optionen: 7.56 - </p> 7.57 - 7.58 - <nobr><a href="__BASEURL__">Weiter zur Startseite</a></nobr> 7.59 - <nobr><a href="#" onclick="window.location.reload()">Anfrage wiederholen</a></nobr> 7.60 - <nobr><a href="http://trac.public-software-group.org/projects/lf" target="_blank">Fehlerbericht erstellen</a></nobr> 7.61 - 7.62 - <hr /> 7.63 - <p> 7.64 - If you write a bug report, please include the following output in your bug report.<br /> 7.65 - Falls Du einen Fehlerbericht erstellst, füge bitte die folgenden Ausgaben mit ein. 7.66 - </p> 7.67 - <tt style="font-size: 75%;"><!-- WEBMCP SLOT system_error --></tt> 7.68 - 7.69 - 7.70 - <div class="layout_trace" id="layout_trace" style="xdisplay: none"> 7.71 - <div id="trace_show" onclick="document.getElementById('trace_content').style.display='block';this.style.display='none';" style="display: none;">TRACE</div> 7.72 - <div id="trace_content"> 7.73 - <!-- WEBMCP SLOT trace --> 7.74 - <div class="trace_close" onclick="document.getElementById('trace_show').style.display='block';document.getElementById('trace_content').style.display='none';">close</div> 7.75 +<head> 7.76 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 7.77 + <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> 7.78 + <title><!-- WEBMCP SLOTNODIV html_title --></title> 7.79 + <link href='http://fonts.googleapis.com/css?family=Signika:300,400,600' rel='stylesheet' type='text/css'> 7.80 + <link href='http://fonts.googleapis.com/css?family=Kreon:300,400,700' rel='stylesheet' type='text/css'> 7.81 + <link href='http://fonts.googleapis.com/css?family=Crimson+Text:600italic' rel='stylesheet' type='text/css'> 7.82 + <link rel="stylesheet" type="text/css" media="screen" href="__BASEURL__/static/gregor.js/gregor.css" /> 7.83 + <link rel="stylesheet" type="text/less" href="__BASEURL__/static/lf3.less" /> 7.84 + <!-- WEBMCP SLOTNODIV html_head --> 7.85 + <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 7.86 + <script type="text/javascript" src="__BASEURL__/static/js/less-1.4.1.min.js"></script> 7.87 + <script type="text/javascript">jsFail = true;</script> 7.88 + <![if !IE]> 7.89 + <script type="text/javascript">jsFail = false;</script> 7.90 + <![endif]> 7.91 + <script type="text/javascript" src="__BASEURL__/static/js/jsprotect.js"></script> 7.92 + <script type="text/javascript" src="__BASEURL__/static/js/partialload.js"></script> 7.93 + <script type="text/javascript">var ui_tabs_active = {};</script> 7.94 + <style> 7.95 + body { 7.96 + background-image: url('__BASEURL__/static/back/berlin2.png'); 7.97 + background-repeat: no-repeat; 7.98 + background-position: left bottom; 7.99 + background-size: 100%; 7.100 + background: #397ab6; 7.101 + } 7.102 + </style> 7.103 +</head> 7.104 +<body style=""> 7.105 +<div class="head_outer"> 7.106 + <div class="head"> 7.107 + <div class="nav"> 7.108 + <!--WEBMCP SLOTNODIV navigation --> 7.109 </div> 7.110 7.111 - </body> 7.112 + <a class="logo" href="__BASEURL__/"> 7.113 + <span class="liquid">Liquid</span><span class="feedback">Feedback</span> 7.114 + <span class="instanceName"><!-- WEBMCP SLOTNODIV instance_name --></span> 7.115 + </a> 7.116 + 7.117 + 7.118 + </div> 7.119 +</div> 7.120 + 7.121 +<div class="page"> 7.122 + <div class="title_outer"> 7.123 + <div class="slot_title">System error</div> 7.124 + </div> 7.125 + 7.126 + <div class="content"> 7.127 + <div class="sidebar"> 7.128 + </div> 7.129 + 7.130 + <div class="main_outer"> 7.131 + <div class="main"> 7.132 + <div class="section"> 7.133 + <div class="sectionHead"> 7.134 + <h1>A system error occured</h1> 7.135 + </div> 7.136 + <div class="sectionRow"> 7.137 + Sorry, a system error occured. 7.138 + <br /> 7.139 + <br /> 7.140 + <br /> 7.141 + <a href="__BASEURL__">Go back to home page</a> 7.142 + </div> 7.143 + </div> 7.144 + </div> 7.145 + </div> 7.146 + </div> 7.147 + <br style="clear: both;" /> 7.148 + <div class="footer"> 7.149 + <!-- WEBMCP SLOTNODIV footer --> 7.150 + </div> 7.151 +</div> 7.152 + 7.153 +<div id="trace_content"> 7.154 + <tt id="system_error"><!-- WEBMCP SLOT system_error --></tt> 7.155 + <hr /> 7.156 + <!-- WEBMCP SLOT trace --> 7.157 +</div> 7.158 + 7.159 +</body> 7.160 </html> 7.161 \ No newline at end of file
8.1 --- a/app/main/admin/_action/area_update.lua Thu Jul 10 01:02:43 2014 +0200 8.2 +++ b/app/main/admin/_action/area_update.lua Thu Jul 10 01:19:48 2014 +0200 8.3 @@ -2,6 +2,13 @@ 8.4 8.5 param.update(area, "unit_id", "name", "description", "active") 8.6 8.7 +if #area.name < 1 then 8.8 + slot.select("error", function() 8.9 + ui.tag{ content = _"Please choose an area name" } 8.10 + end) 8.11 + return false 8.12 +end 8.13 + 8.14 area:save() 8.15 8.16 param.update_relationship{
9.1 --- a/app/main/admin/area_show.lua Thu Jul 10 01:02:43 2014 +0200 9.2 +++ b/app/main/admin/area_show.lua Thu Jul 10 01:19:48 2014 +0200 9.3 @@ -1,25 +1,27 @@ 9.4 local id = param.get_id() 9.5 9.6 +local hint = not id 9.7 + 9.8 local area = Area:by_id(id) or Area:new() 9.9 9.10 if not area.unit_id then 9.11 area.unit_id = param.get("unit_id", atom.integer) 9.12 end 9.13 9.14 -ui.title(_"Create / edit area") 9.15 +ui.titleAdmin(_"area") 9.16 9.17 ui.form{ 9.18 - attr = { class = "vertical" }, 9.19 + attr = { class = "vertical section" }, 9.20 record = area, 9.21 module = "admin", 9.22 action = "area_update", 9.23 routing = { 9.24 - default = { 9.25 + ok = { 9.26 mode = "redirect", 9.27 module = "admin", 9.28 - view = "area_list", 9.29 + view = "index", 9.30 params = { unit_id = area.unit_id } 9.31 - } 9.32 + }, 9.33 }, 9.34 id = id, 9.35 content = function() 9.36 @@ -34,25 +36,38 @@ 9.37 def_policy[#def_policy+1] = record 9.38 end 9.39 9.40 - ui.field.hidden{ name = "unit_id", value = area.unit_id } 9.41 - ui.field.text{ label = _"Unit", value = area.unit.name, readonly = true } 9.42 - ui.field.text{ label = _"Name", name = "name" } 9.43 - ui.field.text{ label = _"Description", name = "description", multiline = true } 9.44 - ui.field.select{ label = _"Default Policy", name = "default_policy", 9.45 - value=area.default_policy and area.default_policy.id or "-1", 9.46 - foreign_records = def_policy, 9.47 - foreign_id = "id", 9.48 - foreign_name = "name" 9.49 - } 9.50 - ui.multiselect{ label = _"Policies", name = "allowed_policies[]", 9.51 - foreign_records = policies, 9.52 - foreign_id = "id", 9.53 - foreign_name = "name", 9.54 - connecting_records = area.allowed_policies or {}, 9.55 - foreign_reference = "id", 9.56 - } 9.57 - slot.put("<br /><br />") 9.58 - ui.field.boolean{ label = _"Active?", name = "active" } 9.59 - ui.submit{ text = _"Save" } 9.60 + 9.61 + ui.section( function() 9.62 + ui.sectionHead( function() 9.63 + ui.heading { level = 1, content = area.name or _"New area" } 9.64 + end ) 9.65 + 9.66 + ui.sectionRow( function() 9.67 + 9.68 + ui.field.hidden{ name = "unit_id", value = area.unit_id } 9.69 + ui.field.text{ label = _"Unit", value = area.unit.name, readonly = true } 9.70 + ui.field.text{ label = _"Name", name = "name" } 9.71 + ui.field.text{ label = _"Description", name = "description", multiline = true } 9.72 + ui.field.select{ label = _"Default Policy", name = "default_policy", 9.73 + value=area.default_policy and area.default_policy.id or "-1", 9.74 + foreign_records = def_policy, 9.75 + foreign_id = "id", 9.76 + foreign_name = "name" 9.77 + } 9.78 + ui.heading { level = 3, content = _"Allowed policies" } 9.79 + ui.multiselect{ name = "allowed_policies[]", 9.80 + foreign_records = policies, 9.81 + foreign_id = "id", 9.82 + foreign_name = "name", 9.83 + connecting_records = area.allowed_policies or {}, 9.84 + foreign_reference = "id", 9.85 + } 9.86 + slot.put("<br /><br />") 9.87 + ui.field.boolean{ label = _"Active?", name = "active", value = hint and true or nil } 9.88 + ui.submit{ text = _"update area" } 9.89 + slot.put(" ") 9.90 + ui.link{ module = "admin", view = "index", content = _"cancel" } 9.91 + end ) 9.92 + end ) 9.93 end 9.94 }
10.1 --- a/app/main/admin/cancel_issue.lua Thu Jul 10 01:02:43 2014 +0200 10.2 +++ b/app/main/admin/cancel_issue.lua Thu Jul 10 01:19:48 2014 +0200 10.3 @@ -1,38 +1,39 @@ 10.4 - 10.5 local id = param.get("id") 10.6 10.7 if not id then 10.8 - ui.title("Cancel issue") 10.9 - ui.actions() 10.10 - ui.form{ 10.11 - module = "admin", 10.12 - view = "cancel_issue", 10.13 - content = function() 10.14 - ui.field.text{ label = _"Issue ID", name = "id" } 10.15 - ui.submit{ text = _"Cancel issue" } 10.16 - end 10.17 - } 10.18 -else 10.19 - 10.20 - local issue = Issue:by_id(id) 10.21 - 10.22 - ui.title(_("Cancel issue #{id}", { id = issue.id })) 10.23 - ui.actions() 10.24 + return 10.25 +end 10.26 + 10.27 +local issue = Issue:by_id(id) 10.28 +issue:load_everything_for_member_id ( app.session.member_id ) 10.29 +issue.initiatives:load_everything_for_member_id ( app.session.member_id ) 10.30 + 10.31 +ui.titleAdmin(_"Cancel issue") 10.32 10.33 +ui.form{ 10.34 + module = "admin", 10.35 + action = "cancel_issue", 10.36 + id = id, 10.37 + attr = { class = "vertical section" }, 10.38 + content = function() 10.39 10.40 - execute.view{ module = "initiative", view = "_list", params = { 10.41 - initiatives_selector = issue:get_reference_selector("initiatives") 10.42 - } } 10.43 + ui.sectionHead( function() 10.44 + ui.heading { level = 1, content = _("Cancel issue ##{id}", { id = issue.id }) } 10.45 + end ) 10.46 10.47 - ui.form{ 10.48 - module = "admin", 10.49 - action = "cancel_issue", 10.50 - id = id, 10.51 - attr = { class = "vertical" }, 10.52 - content = function() 10.53 - ui.field.text{ label = _"Public administrative notice:", name = "admin_notice", multiline = true } 10.54 - ui.submit{ text = _"Cancel issue now" } 10.55 - end 10.56 - } 10.57 + ui.sectionRow( function() 10.58 + execute.view{ module = "initiative", view = "_list", params = { 10.59 + issue = issue, 10.60 + initiatives = issue.initiatives 10.61 + } } 10.62 + end ) 10.63 + 10.64 + ui.sectionRow( function() 10.65 + ui.field.text{ label = _"public administrative notice:", name = "admin_notice", multiline = true } 10.66 + ui.submit{ text = _"cancel issue now" } 10.67 + slot.put(" ") 10.68 + ui.link { module = "admin", view = "index", content = "go back to safety" } 10.69 + end ) 10.70 + end 10.71 +} 10.72 10.73 -end
11.1 --- a/app/main/admin/index.lua Thu Jul 10 01:02:43 2014 +0200 11.2 +++ b/app/main/admin/index.lua Thu Jul 10 01:19:48 2014 +0200 11.3 @@ -1,34 +1,126 @@ 11.4 -slot.put_into("title", _"Admin menu") 11.5 +local units = Unit:get_flattened_tree{ active = true } 11.6 +local policies = Policy:build_selector{}:add_order_by("index"):exec() 11.7 + 11.8 +slot.put_into("title", _"Manage system settings") 11.9 11.10 +ui.sidebar( "tab-members", function() 11.11 + ui.sidebarHead( function() 11.12 + ui.heading { level = 2, content = _"Members" } 11.13 + end ) 11.14 + 11.15 + ui.sidebarSection( function() 11.16 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function() 11.17 + ui.tag { tag = "li", content = function() 11.18 + ui.form{ 11.19 + module = "admin", view = "member_list", 11.20 + content = function() 11.21 + 11.22 + ui.field.text{ label = _"search", name = "search" } 11.23 + 11.24 + ui.submit{ value = _"search" } 11.25 + 11.26 + end 11.27 + } 11.28 + end } 11.29 + end } 11.30 + end ) 11.31 + ui.sidebarSection( "moreLink", function() 11.32 + ui.link{ 11.33 + text = _"Register new member", 11.34 + module = "admin", 11.35 + view = "member_edit" 11.36 + } 11.37 + end ) 11.38 +end ) 11.39 11.40 -ui.tag{ tag = "ul", content = function() 11.41 - ui.tag{ tag= "li", content = function() 11.42 +ui.sidebar( "tab-whatcanido", function() 11.43 + ui.sidebarHead( function() 11.44 + ui.heading { level = 2, content = _"Cancel issue" } 11.45 + end ) 11.46 + 11.47 + ui.sidebarSection( function() 11.48 + ui.form{ 11.49 + module = "admin", 11.50 + view = "cancel_issue", 11.51 + content = function() 11.52 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function() 11.53 + ui.tag { tag = "li", content = function() 11.54 + ui.field.text{ label = _"Issue #", name = "id" } 11.55 + ui.submit{ text = _"cancel issue" } 11.56 + end } 11.57 + end } 11.58 + end 11.59 + } 11.60 + end ) 11.61 +end ) 11.62 + 11.63 +ui.sidebar("tab-whatcanido", function() 11.64 + ui.sidebarHead( function() 11.65 + ui.heading { level = 2, content = _"Policies" } 11.66 + end ) 11.67 + 11.68 + ui.sidebarSection( function() 11.69 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function() 11.70 + for i, policy in ipairs(policies) do 11.71 + ui.tag { tag = "li", content = function() 11.72 + ui.link{ 11.73 + content = policy.name, 11.74 + module = "admin", 11.75 + view = "policy_show", 11.76 + id = policy.id 11.77 + } 11.78 + end } 11.79 + end 11.80 + end } 11.81 + end ) 11.82 + ui.sidebarSection( "moreLink", function() 11.83 ui.link{ 11.84 - text = _"Policies", 11.85 + text = _"Create new policy", 11.86 + module = "admin", 11.87 + view = "policy_show" 11.88 + } 11.89 + end ) 11.90 + ui.sidebarSection( "moreLink", function() 11.91 + ui.link{ 11.92 + text = _"Show policies not in use", 11.93 module = "admin", 11.94 view = "policy_list", 11.95 - } 11.96 - end } 11.97 - ui.tag{ tag= "li", content = function() 11.98 - ui.link{ 11.99 - text = _"Units", 11.100 - module = "admin", 11.101 - view = "unit_list", 11.102 + params = { show_not_in_use = true } 11.103 } 11.104 - end } 11.105 - ui.tag{ tag= "li", content = function() 11.106 - ui.link{ 11.107 - text = _"Members", 11.108 - module = "admin", 11.109 - view = "member_list", 11.110 - } 11.111 - end } 11.112 - ui.tag{ tag= "li", content = function() 11.113 - ui.link{ 11.114 - text = _"Cancel issue", 11.115 - module = "admin", 11.116 - view = "cancel_issue", 11.117 - } 11.118 - end } 11.119 -end } 11.120 + end ) 11.121 +end ) 11.122 + 11.123 + 11.124 +ui.section( function() 11.125 + ui.sectionHead( function() 11.126 + ui.heading { level = 1, content = _"Organizational units and subject areas" } 11.127 + end ) 11.128 + ui.sectionRow( function() 11.129 11.130 + for i_unit, unit in ipairs(units) do 11.131 + ui.container { 11.132 + attr = { style = "margin-left: " .. ((unit.depth - 1)* 2) .. "em;" }, 11.133 + content = function () 11.134 + ui.heading { level = 1, content = function () 11.135 + ui.link{ text = unit.name, module = "admin", view = "unit_edit", id = unit.id } 11.136 + end } 11.137 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 11.138 + for i, area in ipairs(unit:get_reference_selector("areas"):add_order_by("name"):exec()) do 11.139 + ui.tag { tag = "li", content = function () 11.140 + ui.link{ text = area.name, module = "admin", view = "area_show", id = area.id } 11.141 + end } 11.142 + end 11.143 + ui.tag { tag = "li", content = function () 11.144 + ui.link { module = "admin", view = "area_show", params = { unit_id = unit.id }, content = _"+ add new subject area" } 11.145 + end } 11.146 + slot.put("<br />") 11.147 + end } 11.148 + end 11.149 + } 11.150 + end 11.151 + 11.152 + slot.put("<br />") 11.153 + ui.link { module = "admin", view = "unit_edit", content = _"+ add new organizational unit" } 11.154 + 11.155 + end) 11.156 +end)
12.1 --- a/app/main/admin/member_edit.lua Thu Jul 10 01:02:43 2014 +0200 12.2 +++ b/app/main/admin/member_edit.lua Thu Jul 10 01:19:48 2014 +0200 12.3 @@ -2,11 +2,7 @@ 12.4 12.5 local member = Member:by_id(id) 12.6 12.7 -if member then 12.8 - ui.title(_("Member: '#{identification}' (#{name})", { identification = member.identification, name = member.name })) 12.9 -else 12.10 - ui.title(_"Register new member") 12.11 -end 12.12 +ui.title(_"member") 12.13 12.14 local units_selector = Unit:new_selector() 12.15 12.16 @@ -19,7 +15,7 @@ 12.17 local units = units_selector:exec() 12.18 12.19 ui.form{ 12.20 - attr = { class = "vertical" }, 12.21 + attr = { class = "vertical section" }, 12.22 module = "admin", 12.23 action = "member_update", 12.24 id = member and member.id, 12.25 @@ -29,43 +25,54 @@ 12.26 default = { 12.27 mode = "redirect", 12.28 modules = "admin", 12.29 - view = "member_list" 12.30 + view = "index" 12.31 } 12.32 }, 12.33 content = function() 12.34 - ui.field.text{ label = _"Identification", name = "identification" } 12.35 - ui.field.text{ label = _"Notification email", name = "notify_email" } 12.36 - if member and member.activated then 12.37 - ui.field.text{ label = _"Screen name", name = "name" } 12.38 - ui.field.text{ label = _"Login name", name = "login" } 12.39 - end 12.40 - ui.field.boolean{ label = _"Admin?", name = "admin" } 12.41 12.42 - slot.put("<br />") 12.43 - 12.44 - for i, unit in ipairs(units) do 12.45 - ui.field.boolean{ 12.46 - name = "unit_" .. unit.id, 12.47 - label = unit.name, 12.48 - value = unit.voting_right 12.49 + ui.sectionHead( function() 12.50 + ui.heading { level = 1, content = member and member.name or _"New member" } 12.51 + if member and member.identification then 12.52 + ui.heading { level = 3, content = member.identification } 12.53 + end 12.54 + end ) 12.55 + 12.56 + ui.sectionRow( function() 12.57 + ui.field.text{ label = _"Identification", name = "identification" } 12.58 + ui.field.text{ label = _"Notification email", name = "notify_email" } 12.59 + if member and member.activated then 12.60 + ui.field.text{ label = _"Screen name", name = "name" } 12.61 + ui.field.text{ label = _"Login name", name = "login" } 12.62 + end 12.63 + 12.64 + for i, unit in ipairs(units) do 12.65 + ui.field.boolean{ 12.66 + name = "unit_" .. unit.id, 12.67 + label = unit.name, 12.68 + value = unit.voting_right 12.69 + } 12.70 + end 12.71 + slot.put("<br /><br />") 12.72 + 12.73 + if not member or not member.activated then 12.74 + ui.field.boolean{ label = _"Send invite?", name = "invite_member" } 12.75 + end 12.76 + 12.77 + if member and member.activated then 12.78 + ui.field.boolean{ label = _"Lock member?", name = "locked" } 12.79 + end 12.80 + 12.81 + ui.field.boolean{ 12.82 + label = _"Member inactive?", name = "deactivate", 12.83 + readonly = member and member.active, value = member and member.active == false 12.84 } 12.85 - end 12.86 - slot.put("<br /><br />") 12.87 - 12.88 - if not member or not member.activated then 12.89 - ui.field.boolean{ label = _"Send invite?", name = "invite_member" } 12.90 - end 12.91 - 12.92 - if member and member.activated then 12.93 - ui.field.boolean{ label = _"Lock member?", name = "locked" } 12.94 - end 12.95 - 12.96 - ui.field.boolean{ 12.97 - label = _"Member inactive?", name = "deactivate", 12.98 - readonly = member and member.active, value = member and member.active == false 12.99 - } 12.100 - 12.101 - slot.put("<br />") 12.102 - ui.submit{ text = _"Save" } 12.103 + 12.104 + slot.put("<br />") 12.105 + ui.field.boolean{ label = _"Admin?", name = "admin" } 12.106 + slot.put("<br />") 12.107 + ui.submit{ text = _"update member" } 12.108 + slot.put(" ") 12.109 + ui.link { module = "admin", view = "index", content = _"cancel" } 12.110 + end ) 12.111 end 12.112 }
13.1 --- a/app/main/admin/member_list.lua Thu Jul 10 01:02:43 2014 +0200 13.2 +++ b/app/main/admin/member_list.lua Thu Jul 10 01:19:48 2014 +0200 13.3 @@ -1,96 +1,100 @@ 13.4 local search = param.get("search") 13.5 13.6 -ui.title(_"Member list") 13.7 +ui.titleAdmin(_"Member list") 13.8 + 13.9 +ui.section( function() 13.10 + 13.11 + ui.sectionHead( function() 13.12 + ui.heading { level = 1, content = _"Member list" } 13.13 + end ) 13.14 13.15 -ui.actions(function() 13.16 - ui.link{ 13.17 - attr = { class = { "admin_only" } }, 13.18 - text = _"Register new member", 13.19 - module = "admin", 13.20 - view = "member_edit" 13.21 - } 13.22 -end) 13.23 - 13.24 - 13.25 -ui.form{ 13.26 - module = "admin", view = "member_list", 13.27 - content = function() 13.28 + ui.sectionRow( function () 13.29 + ui.form{ 13.30 + module = "admin", view = "member_list", 13.31 + content = function() 13.32 + 13.33 + ui.field.text{ label = _"search", name = "search", value = search } 13.34 + 13.35 + ui.submit{ value = _"search" } 13.36 + 13.37 + end 13.38 + } 13.39 + end ) 13.40 13.41 - ui.field.text{ label = _"Search for members", name = "search" } 13.42 - 13.43 - ui.submit{ value = _"Start search" } 13.44 - 13.45 - end 13.46 -} 13.47 13.48 -if not search then 13.49 - return 13.50 -end 13.51 - 13.52 -local members_selector = Member:build_selector{ 13.53 - admin_search = search, 13.54 - order = "identification" 13.55 -} 13.56 + ui.sectionRow( function () 13.57 + local members_selector = Member:build_selector{ 13.58 + admin_search = search, 13.59 + order = "identification" 13.60 + } 13.61 13.62 13.63 -ui.paginate{ 13.64 - selector = members_selector, 13.65 - per_page = 30, 13.66 - content = function() 13.67 - ui.list{ 13.68 - records = members_selector:exec(), 13.69 - columns = { 13.70 - { 13.71 - field_attr = { style = "text-align: right;" }, 13.72 - label = _"Id", 13.73 - name = "id" 13.74 - }, 13.75 - { 13.76 - label = _"Identification", 13.77 - name = "identification" 13.78 - }, 13.79 - { 13.80 - label = _"Screen name", 13.81 - name = "name" 13.82 - }, 13.83 - { 13.84 - label = _"Admin?", 13.85 - content = function(record) 13.86 - if record.admin then 13.87 - ui.field.text{ value = "admin" } 13.88 - end 13.89 - end 13.90 - }, 13.91 - { 13.92 - content = function(record) 13.93 - if not record.activated then 13.94 - ui.field.text{ value = "not activated" } 13.95 - elseif not record.active then 13.96 - ui.field.text{ value = "inactive" } 13.97 - else 13.98 - ui.field.text{ value = "active" } 13.99 - end 13.100 - end 13.101 - }, 13.102 - { 13.103 - content = function(record) 13.104 - if record.locked then 13.105 - ui.field.text{ value = "locked" } 13.106 - end 13.107 - end 13.108 - }, 13.109 - { 13.110 - content = function(record) 13.111 - ui.link{ 13.112 - attr = { class = "action admin_only" }, 13.113 - text = _"Edit", 13.114 - module = "admin", 13.115 - view = "member_edit", 13.116 - id = record.id 13.117 - } 13.118 - end 13.119 + ui.paginate{ 13.120 + selector = members_selector, 13.121 + per_page = 30, 13.122 + content = function() 13.123 + ui.list{ 13.124 + records = members_selector:exec(), 13.125 + columns = { 13.126 + { 13.127 + label = _"Id", 13.128 + content = function(record) 13.129 + ui.link{ 13.130 + text = record.id, 13.131 + module = "admin", 13.132 + view = "member_edit", 13.133 + id = record.id 13.134 + } 13.135 + end 13.136 + }, 13.137 + { 13.138 + label = _"Identification", 13.139 + content = function(record) 13.140 + ui.link{ 13.141 + text = record.identification or "", 13.142 + module = "admin", 13.143 + view = "member_edit", 13.144 + id = record.id 13.145 + } 13.146 + end 13.147 + }, 13.148 + { 13.149 + label = _"Screen name", 13.150 + content = function(record) 13.151 + ui.link{ 13.152 + text = record.name or "", 13.153 + module = "admin", 13.154 + view = "member_edit", 13.155 + id = record.id 13.156 + } 13.157 + end 13.158 + }, 13.159 + { 13.160 + content = function(record) 13.161 + if record.admin then 13.162 + ui.field.text{ value = "admin" } 13.163 + end 13.164 + end 13.165 + }, 13.166 + { 13.167 + content = function(record) 13.168 + if not record.activated then 13.169 + ui.field.text{ value = "not activated" } 13.170 + elseif not record.active then 13.171 + ui.field.text{ value = "inactive" } 13.172 + end 13.173 + end 13.174 + }, 13.175 + { 13.176 + content = function(record) 13.177 + if record.locked then 13.178 + ui.field.text{ value = "locked" } 13.179 + end 13.180 + end 13.181 + }, 13.182 + } 13.183 } 13.184 - } 13.185 + end 13.186 } 13.187 - end 13.188 -} 13.189 \ No newline at end of file 13.190 + end ) 13.191 +end ) 13.192 \ No newline at end of file
14.1 --- a/app/main/admin/policy_list.lua Thu Jul 10 01:02:43 2014 +0200 14.2 +++ b/app/main/admin/policy_list.lua Thu Jul 10 01:19:48 2014 +0200 14.3 @@ -3,52 +3,58 @@ 14.4 local policies = Policy:build_selector{ active = not show_not_in_use }:exec() 14.5 14.6 14.7 -ui.title(_"Policy list") 14.8 +ui.titleAdmin(_"Policy list") 14.9 14.10 +ui.section( function() 14.11 + ui.sectionHead( function() 14.12 + ui.heading { level = 1, content = _"Policy list" } 14.13 + end ) 14.14 + 14.15 + ui.sectionRow( function() 14.16 14.17 -ui.actions(function() 14.18 + if show_not_in_use then 14.19 + ui.link{ 14.20 + text = _"Show policies in use", 14.21 + module = "admin", 14.22 + view = "policy_list" 14.23 + } 14.24 14.25 - if show_not_in_use then 14.26 - ui.link{ 14.27 - text = _"Show policies in use", 14.28 - module = "admin", 14.29 - view = "policy_list" 14.30 + else 14.31 + ui.link{ 14.32 + text = _"Create new policy", 14.33 + module = "admin", 14.34 + view = "policy_show" 14.35 + } 14.36 + slot.put(" · ") 14.37 + ui.link{ 14.38 + text = _"Show policies not in use", 14.39 + module = "admin", 14.40 + view = "policy_list", 14.41 + params = { show_not_in_use = true } 14.42 + } 14.43 + 14.44 + end 14.45 + 14.46 + end ) 14.47 + 14.48 + ui.sectionRow( function() 14.49 + 14.50 + ui.list{ 14.51 + records = policies, 14.52 + columns = { 14.53 + 14.54 + { content = function(record) 14.55 + ui.link{ 14.56 + text = record.name, 14.57 + module = "admin", 14.58 + view = "policy_show", 14.59 + id = record.id 14.60 + } 14.61 + end 14.62 + } 14.63 + 14.64 + } 14.65 } 14.66 14.67 - else 14.68 - ui.link{ 14.69 - text = _"Create new policy", 14.70 - module = "admin", 14.71 - view = "policy_show" 14.72 - } 14.73 - slot.put(" · ") 14.74 - ui.link{ 14.75 - text = _"Show policies not in use", 14.76 - module = "admin", 14.77 - view = "policy_list", 14.78 - params = { show_not_in_use = true } 14.79 - } 14.80 - 14.81 - end 14.82 - 14.83 -end) 14.84 - 14.85 - 14.86 -ui.list{ 14.87 - records = policies, 14.88 - columns = { 14.89 - 14.90 - { label = _"Policy", name = "name" }, 14.91 - 14.92 - { content = function(record) 14.93 - ui.link{ 14.94 - text = _"Edit", 14.95 - module = "admin", 14.96 - view = "policy_show", 14.97 - id = record.id 14.98 - } 14.99 - end 14.100 - } 14.101 - 14.102 - } 14.103 -} 14.104 \ No newline at end of file 14.105 + end ) 14.106 +end ) 14.107 \ No newline at end of file
15.1 --- a/app/main/admin/policy_show.lua Thu Jul 10 01:02:43 2014 +0200 15.2 +++ b/app/main/admin/policy_show.lua Thu Jul 10 01:19:48 2014 +0200 15.3 @@ -1,59 +1,71 @@ 15.4 local policy = Policy:by_id(param.get_id()) or Policy:new() 15.5 15.6 -ui.title(_"Create / edit policy") 15.7 +local hint = not policy.id 15.8 + 15.9 +ui.titleAdmin(policy.name or _"New policy") 15.10 + 15.11 +ui.section( function() 15.12 15.13 -ui.form{ 15.14 - attr = { class = "vertical" }, 15.15 - record = policy, 15.16 - module = "admin", 15.17 - action = "policy_update", 15.18 - routing = { 15.19 - default = { 15.20 - mode = "redirect", 15.21 + ui.sectionHead( function() 15.22 + ui.heading { level = 1, content = _"Policy" } 15.23 + end ) 15.24 + ui.sectionRow( function() 15.25 + ui.form{ 15.26 + attr = { class = "vertical" }, 15.27 + record = policy, 15.28 module = "admin", 15.29 - view = "policy_list" 15.30 - } 15.31 - }, 15.32 - id = policy.id, 15.33 - content = function() 15.34 + action = "policy_update", 15.35 + routing = { 15.36 + default = { 15.37 + mode = "redirect", 15.38 + module = "admin", 15.39 + view = "index" 15.40 + } 15.41 + }, 15.42 + id = policy.id, 15.43 + content = function() 15.44 15.45 - ui.field.text{ label = _"Index", name = "index" } 15.46 - 15.47 - ui.field.text{ label = _"Name", name = "name" } 15.48 - ui.field.text{ label = _"Description", name = "description", multiline = true } 15.49 - ui.field.text{ label = _"Hint", readonly = true, 15.50 - value = _"Interval format:" .. " 3 mons 2 weeks 1 day 10:30:15" } 15.51 + ui.field.text{ label = _"Index", name = "index", value = hint and "1" or nil } 15.52 15.53 - ui.field.text{ label = _"Admission time", name = "admission_time" } 15.54 - ui.field.text{ label = _"Discussion time", name = "discussion_time" } 15.55 - ui.field.text{ label = _"Verification time", name = "verification_time" } 15.56 - ui.field.text{ label = _"Voting time", name = "voting_time" } 15.57 + ui.field.text{ label = _"Name", name = "name" } 15.58 + ui.field.text{ label = _"Description", name = "description", multiline = true } 15.59 + ui.field.text{ label = _"Hint", readonly = true, 15.60 + value = _"Interval format:" .. " 3 mons 2 weeks 1 day 10:30:15" } 15.61 15.62 - ui.field.text{ label = _"Issue quorum numerator", name = "issue_quorum_num" } 15.63 - ui.field.text{ label = _"Issue quorum denumerator", name = "issue_quorum_den" } 15.64 + ui.field.text{ label = _"Admission time", name = "admission_time", value = hint and "30 days" or nil } 15.65 + ui.field.text{ label = _"Discussion time", name = "discussion_time", value = hint and "30 days" or nil } 15.66 + ui.field.text{ label = _"Verification time", name = "verification_time", value = hint and "15 days" or nil } 15.67 + ui.field.text{ label = _"Voting time", name = "voting_time", value = hint and "15 days" or nil } 15.68 15.69 - ui.field.text{ label = _"Initiative quorum numerator", name = "initiative_quorum_num" } 15.70 - ui.field.text{ label = _"Initiative quorum denumerator", name = "initiative_quorum_den" } 15.71 + ui.field.text{ label = _"Issue quorum numerator", name = "issue_quorum_num", value = hint and "10" or nil } 15.72 + ui.field.text{ label = _"Issue quorum denominator", name = "issue_quorum_den", value = hint and "100" or nil } 15.73 + 15.74 + ui.field.text{ label = _"Initiative quorum numerator", name = "initiative_quorum_num", value = hint and "10" or nil } 15.75 + ui.field.text{ label = _"Initiative quorum denominator", name = "initiative_quorum_den", value = hint and "100" or nil } 15.76 15.77 - ui.field.text{ label = _"Direct majority numerator", name = "direct_majority_num" } 15.78 - ui.field.text{ label = _"Direct majority denumerator", name = "direct_majority_den" } 15.79 - ui.field.boolean{ label = _"Strict direct majority", name = "direct_majority_strict" } 15.80 - ui.field.text{ label = _"Direct majority positive", name = "direct_majority_positive" } 15.81 - ui.field.text{ label = _"Direct majority non negative", name = "direct_majority_non_negative" } 15.82 + ui.field.text{ label = _"Direct majority numerator", name = "direct_majority_num", value = hint and "50" or nil } 15.83 + ui.field.text{ label = _"Direct majority denominator", name = "direct_majority_den", value = hint and "100" or nil } 15.84 + ui.field.boolean{ label = _"Strict direct majority", name = "direct_majority_strict", value = hint and true or nil } 15.85 + ui.field.text{ label = _"Direct majority positive", name = "direct_majority_positive", value = hint and "0" or nil } 15.86 + ui.field.text{ label = _"Direct majority non negative", name = "direct_majority_non_negative", value = hint and "0" or nil } 15.87 15.88 - ui.field.text{ label = _"Indirect majority numerator", name = "indirect_majority_num" } 15.89 - ui.field.text{ label = _"Indirect majority denumerator", name = "indirect_majority_den" } 15.90 - ui.field.boolean{ label = _"Strict indirect majority", name = "indirect_majority_strict" } 15.91 - ui.field.text{ label = _"Indirect majority positive", name = "indirect_majority_positive" } 15.92 - ui.field.text{ label = _"Indirect majority non negative", name = "indirect_majority_non_negative" } 15.93 + ui.field.text{ label = _"Indirect majority numerator", name = "indirect_majority_num", value = hint and "50" or nil } 15.94 + ui.field.text{ label = _"Indirect majority denominator", name = "indirect_majority_den", value = hint and "100" or nil } 15.95 + ui.field.boolean{ label = _"Strict indirect majority", name = "indirect_majority_strict", value = hint and true or nil } 15.96 + ui.field.text{ label = _"Indirect majority positive", name = "indirect_majority_positive", value = hint and "0" or nil } 15.97 + ui.field.text{ label = _"Indirect majority non negative", name = "indirect_majority_non_negative", value = hint and "0" or nil } 15.98 15.99 - ui.field.boolean{ label = _"No reverse beat path", name = "no_reverse_beat_path" } 15.100 - ui.field.boolean{ label = _"No multistage majority", name = "no_multistage_majority" } 15.101 - ui.field.boolean{ label = _"Polling mode", name = "polling" } 15.102 + ui.field.boolean{ label = _"No reverse beat path", name = "no_reverse_beat_path", value = hint and false or nil } 15.103 + ui.field.boolean{ label = _"No multistage majority", name = "no_multistage_majority", value = hint and false or nil } 15.104 + ui.field.boolean{ label = _"Polling mode", name = "polling", value = hint and false or nil } 15.105 15.106 15.107 - ui.field.boolean{ label = _"Active?", name = "active" } 15.108 + ui.field.boolean{ label = _"Active?", name = "active", value = hint and true or nil } 15.109 15.110 - ui.submit{ text = _"Save" } 15.111 - end 15.112 -} 15.113 + ui.submit{ text = _"update policy" } 15.114 + slot.put(" ") 15.115 + ui.link { module = "admin", view = "index", content = _"cancel" } 15.116 + end 15.117 + } 15.118 + end ) 15.119 +end ) 15.120 \ No newline at end of file
16.1 --- a/app/main/admin/unit_edit.lua Thu Jul 10 01:02:43 2014 +0200 16.2 +++ b/app/main/admin/unit_edit.lua Thu Jul 10 01:19:48 2014 +0200 16.3 @@ -3,9 +3,7 @@ 16.4 local unit = Unit:by_id(id) 16.5 16.6 if unit then 16.7 - ui.title(_("Unit: '#{name}'", { name = unit.name })) 16.8 -else 16.9 - ui.title(_"Add new unit") 16.10 + ui.titleAdmin(_"Organizational unit") 16.11 end 16.12 16.13 local units = { 16.14 @@ -17,7 +15,7 @@ 16.15 end 16.16 16.17 ui.form{ 16.18 - attr = { class = "vertical" }, 16.19 + attr = { class = "vertical section" }, 16.20 module = "admin", 16.21 action = "unit_update", 16.22 id = unit and unit.id, 16.23 @@ -26,22 +24,29 @@ 16.24 default = { 16.25 mode = "redirect", 16.26 modules = "admin", 16.27 - view = "unit_list" 16.28 + view = "index" 16.29 } 16.30 }, 16.31 content = function() 16.32 - ui.field.select{ 16.33 - label = _"Parent unit", 16.34 - name = "parent_id", 16.35 - foreign_records = units, 16.36 - foreign_id = "id", 16.37 - foreign_name = "name" 16.38 - } 16.39 - ui.field.text{ label = _"Name", name = "name" } 16.40 - ui.field.text{ label = _"Description", name = "description", multiline = true } 16.41 - ui.field.boolean{ label = _"Active?", name = "active" } 16.42 + ui.sectionHead( function() 16.43 + ui.heading { level = 1, content = unit and unit.name or _"New organizational unit" } 16.44 + end ) 16.45 + ui.sectionRow( function() 16.46 + ui.field.select{ 16.47 + label = _"Parent unit", 16.48 + name = "parent_id", 16.49 + foreign_records = units, 16.50 + foreign_id = "id", 16.51 + foreign_name = "name" 16.52 + } 16.53 + ui.field.text{ label = _"Name", name = "name" } 16.54 + ui.field.text{ label = _"Description", name = "description", multiline = true } 16.55 + ui.field.boolean{ label = _"Active?", name = "active" } 16.56 16.57 - slot.put("<br />") 16.58 - ui.submit{ text = _"Save" } 16.59 + slot.put("<br />") 16.60 + ui.submit{ text = _"update unit" } 16.61 + slot.put(" ") 16.62 + ui.link{ module = "admin", view = "index", content = _"cancel" } 16.63 + end ) 16.64 end 16.65 }
17.1 --- a/app/main/area/_head.lua Thu Jul 10 01:02:43 2014 +0200 17.2 +++ b/app/main/area/_head.lua Thu Jul 10 01:19:48 2014 +0200 17.3 @@ -1,110 +1,39 @@ 17.4 local area = param.get("area", "table") 17.5 local member = param.get("member", "table") 17.6 17.7 -local show_content = param.get("show_content", atom.boolean) 17.8 +ui.title ( function () 17.9 17.10 -if app.session.member_id then 17.11 - area:load_delegation_info_once_for_member_id(app.session.member_id) 17.12 -end 17.13 + -- unit link 17.14 + ui.link { 17.15 + attr = { class = "unit" }, 17.16 + content = function() 17.17 + ui.tag{ attr = { class = "name" }, content = area.unit.name } 17.18 + end, 17.19 + module = "unit", view = "show", 17.20 + id = area.unit.id 17.21 + } 17.22 17.23 -if not param.get("hide_unit", atom.boolean) then 17.24 - execute.view{ module = "unit", view = "_head", params = { unit = area.unit, member = member } } 17.25 -end 17.26 + ui.tag { attr = { class = "spacer" }, content = function() 17.27 + slot.put ( " » " ) 17.28 + end } 17.29 17.30 -ui.container{ attr = { class = "area_head" }, content = function() 17.31 - 17.32 - execute.view{ module = "delegation", view = "_info", params = { area = area, member = member } } 17.33 + ui.tag { attr = { class = "area" }, content = function() 17.34 + -- area link 17.35 + ui.link { 17.36 + content = function() 17.37 + ui.tag{ attr = { class = "name" }, content = area.name } 17.38 + end, 17.39 + module = "area", view = "show", 17.40 + id = area.id 17.41 + } 17.42 + 17.43 + slot.put ( " " ) 17.44 17.45 - ui.container{ attr = { class = "title" }, content = function() 17.46 - -- area name 17.47 - ui.link{ 17.48 - module = "area", view = "show", id = area.id, 17.49 - attr = { class = "area_name" }, content = area.name 17.50 + execute.view { 17.51 + module = "delegation", view = "_info", params = { 17.52 + area = area, member = member, for_title = true 17.53 + } 17.54 } 17.55 end } 17.56 17.57 - if show_content then 17.58 - 17.59 - ui.container{ attr = { class = "content" }, content = function() 17.60 - 17.61 - -- actions (members with appropriate voting right only) 17.62 - if member then 17.63 - 17.64 - -- membership 17.65 - local membership = Membership:by_pk(area.id, member.id) 17.66 - 17.67 - if membership then 17.68 - 17.69 - if app.session.member_id == member.id then 17.70 - ui.tag{ content = _"You are participating in this area" } 17.71 - slot.put(" ") 17.72 - ui.tag{ content = function() 17.73 - slot.put("(") 17.74 - ui.link{ 17.75 - text = _"Withdraw", 17.76 - module = "membership", 17.77 - action = "update", 17.78 - params = { area_id = area.id, delete = true }, 17.79 - routing = { 17.80 - default = { 17.81 - mode = "redirect", 17.82 - module = request.get_module(), 17.83 - view = request.get_view(), 17.84 - id = param.get_id_cgi(), 17.85 - params = param.get_all_cgi() 17.86 - } 17.87 - } 17.88 - } 17.89 - slot.put(")") 17.90 - end } 17.91 - else 17.92 - ui.tag{ content = _"Member is participating in this area" } 17.93 - end 17.94 - 17.95 - elseif app.session.member_id == member.id and member:has_voting_right_for_unit_id(area.unit_id) then 17.96 - ui.link{ 17.97 - text = _"Participate in this area", 17.98 - module = "membership", 17.99 - action = "update", 17.100 - params = { area_id = area.id }, 17.101 - routing = { 17.102 - default = { 17.103 - mode = "redirect", 17.104 - module = request.get_module(), 17.105 - view = request.get_view(), 17.106 - id = param.get_id_cgi(), 17.107 - params = param.get_all_cgi() 17.108 - } 17.109 - } 17.110 - } 17.111 - end 17.112 - 17.113 - if app.session.member_id == member.id and app.session.member:has_voting_right_for_unit_id(area.unit_id) then 17.114 - 17.115 - slot.put(" · ") 17.116 - if area.delegation_info.own_delegation_scope ~= "area" then 17.117 - ui.link{ text = _"Delegate area", module = "delegation", view = "show", params = { area_id = area.id } } 17.118 - else 17.119 - ui.link{ text = _"Change area delegation", module = "delegation", view = "show", params = { area_id = area.id } } 17.120 - end 17.121 - slot.put(" · ") 17.122 - 17.123 - ui.link{ 17.124 - content = function() 17.125 - slot.put(_"Create new issue") 17.126 - end, 17.127 - module = "initiative", 17.128 - view = "new", 17.129 - params = { area_id = area.id } 17.130 - } 17.131 - end 17.132 - 17.133 - end 17.134 - 17.135 - end } 17.136 - 17.137 - else 17.138 - slot.put("<br />") 17.139 - end 17.140 - 17.141 -end } 17.142 \ No newline at end of file 17.143 +end ) 17.144 \ No newline at end of file
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/app/main/area/_issue_list.lua Thu Jul 10 01:19:48 2014 +0200 18.3 @@ -0,0 +1,43 @@ 18.4 +local issues_selector = param.get("issues_selector", "table") 18.5 +local phase = param.get("phase") 18.6 + 18.7 +if phase == "admission" then 18.8 + headline = _"Issues in admission phase" 18.9 +elseif phase == "discussion" then 18.10 + headline = _"Issues in discussion phase" 18.11 +elseif phase == "verification" then 18.12 + headline = _"Issues in verification phase" 18.13 +elseif phase == "voting" then 18.14 + headline = _"Issues in voting phase" 18.15 +elseif phase == "closed" then 18.16 + headline = _"Closed issues" 18.17 +end 18.18 + 18.19 +ui.heading { level = "1", content = headline } 18.20 + 18.21 +local issues = issues_selector:exec() 18.22 + 18.23 +ui.tag { 18.24 + tag = "ul", 18.25 + attr = { class = { "issues" } }, 18.26 + content = function () 18.27 + 18.28 + for i, issue in ipairs(issues) do 18.29 + 18.30 + ui.tag { tag = "li", content = function () 18.31 + ui.heading { level = 2, content = issue.name } 18.32 + 18.33 + execute.view { 18.34 + module = "initiative", view = "_list", params = { 18.35 + initiatives = issue.initiatives, 18.36 + state = phase 18.37 + } 18.38 + } 18.39 + 18.40 + slot.put ( '<hr class="nice" />' ) 18.41 + 18.42 + end } 18.43 + 18.44 + end 18.45 + end 18.46 +} 18.47 \ No newline at end of file
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/app/main/area/_sidebar_members.lua Thu Jul 10 01:19:48 2014 +0200 19.3 @@ -0,0 +1,33 @@ 19.4 +if not app.session:has_access("all_pseudonymous") then 19.5 + return 19.6 +end 19.7 + 19.8 +local area = param.get("area", "table") 19.9 +local members_selector = Member:new_selector() 19.10 + :join("membership", nil, { "membership.member_id = member.id AND membership.area_id = ?", area.id }) 19.11 + :add_where("member.active") 19.12 + :limit(50) 19.13 + 19.14 +ui.sidebar ( "tab-members", function () 19.15 + ui.sidebarHead( function () 19.16 + ui.heading { 19.17 + level = 2, 19.18 + content = _("Subscribed members (#{count})", { 19.19 + count = area.direct_member_count 19.20 + }) 19.21 + } 19.22 + end ) 19.23 + execute.view { 19.24 + module = 'member', view = '_list', params = { 19.25 + members_selector = members_selector, 19.26 + no_filter = true, no_paginate = true, 19.27 + member_class = "sidebarRow sidebarRowNarrow" 19.28 + } 19.29 + } 19.30 + if area.direct_member_count > members_selector:count() then 19.31 + ui.link { 19.32 + text = _"Show all members", 19.33 + module = "member", view = "list" 19.34 + } 19.35 + end 19.36 +end )
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 20.2 +++ b/app/main/area/_sidebar_whatcanido.lua Thu Jul 10 01:19:48 2014 +0200 20.3 @@ -0,0 +1,168 @@ 20.4 +local member = param.get ( "member", "table" ) or app.session.member 20.5 + 20.6 +local area = param.get ( "area", "table" ) 20.7 + 20.8 +local participating_trustee_id 20.9 +local participating_trustee_name 20.10 +if member then 20.11 + if area.delegation_info.first_trustee_participation then 20.12 + participating_trustee_id = area.delegation_info.first_trustee_id 20.13 + participating_trustee_name = area.delegation_info.first_trustee_name 20.14 + elseif area.delegation_info.other_trustee_participation then 20.15 + participating_trustee_id = area.delegation_info.other_trustee_id 20.16 + participating_trustee_name = area.delegation_info.other_trustee_name 20.17 + end 20.18 +end 20.19 + 20.20 +ui.sidebar ( "tab-whatcanido", function () 20.21 + 20.22 + ui.sidebarHeadWhatCanIDo() 20.23 + 20.24 + if member and not app.session.member:has_voting_right_for_unit_id(area.unit_id) then 20.25 + ui.sidebarSection( _"You are not entitled to vote in this unit" ) 20.26 + end 20.27 + 20.28 + if member and app.session.member:has_voting_right_for_unit_id(area.unit_id) then 20.29 + if not area.delegation_info.own_participation then 20.30 + ui.sidebarSection ( function () 20.31 + 20.32 + ui.heading { 20.33 + level = 3, 20.34 + content = _"I want to participate in this subject area" 20.35 + } 20.36 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 20.37 + ui.tag { tag = "li", content = function () 20.38 + ui.tag { content = function () 20.39 + ui.link { 20.40 + module = "membership", action = "update", 20.41 + routing = { default = { 20.42 + mode = "redirect", module = "area", view = "show", id = area.id 20.43 + } }, 20.44 + params = { area_id = area.id }, 20.45 + text = _"subscribe" 20.46 + } 20.47 + end } 20.48 + end } 20.49 + end } 20.50 + end ) 20.51 + end 20.52 + 20.53 + if area.delegation_info.own_participation then 20.54 + ui.sidebarSection ( function () 20.55 + ui.image{ attr = { class = "right" }, static = "icons/48/star.png" } 20.56 + ui.heading { 20.57 + level = 3, 20.58 + content = _"You are subscribed for this subject area" 20.59 + } 20.60 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 20.61 + ui.tag { tag = "li", content = function () 20.62 + ui.tag { content = function () 20.63 + ui.link { 20.64 + module = "membership", action = "update", 20.65 + routing = { default = { 20.66 + mode = "redirect", module = "area", view = "show", id = area.id 20.67 + } }, 20.68 + params = { area_id = area.id, delete = true }, 20.69 + text = _"unsubscribe" 20.70 + } 20.71 + end } 20.72 + end } 20.73 + end } 20.74 + end ) 20.75 + end 20.76 + 20.77 + 20.78 + ui.sidebarSection ( function () 20.79 + 20.80 + 20.81 + if not area.delegation_info.first_trustee_id then 20.82 + ui.heading{ level = 3, content = _"I want to delegate this subject area" } 20.83 + else 20.84 + ui.container { attr = { class = "right" }, content = function() 20.85 + local member = Member:by_id(area.delegation_info.first_trustee_id) 20.86 + execute.view{ 20.87 + module = "member_image", 20.88 + view = "_show", 20.89 + params = { 20.90 + member = member, 20.91 + image_type = "avatar", 20.92 + show_dummy = true 20.93 + } 20.94 + } 20.95 + end } 20.96 + ui.heading{ level = 3, content = _"You delegated this subject area" } 20.97 + end 20.98 + 20.99 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 20.100 + if area.delegation_info.own_delegation_scope == "unit" then 20.101 + ui.tag { tag = "li", content = function () 20.102 + ui.link { 20.103 + module = "delegation", view = "show", params = { 20.104 + unit_id = area.unit_id, 20.105 + }, 20.106 + content = _("change/revoke delegation of organizational unit") 20.107 + } 20.108 + end } 20.109 + end 20.110 + 20.111 + if area.delegation_info.own_delegation_scope == nil then 20.112 + ui.tag { tag = "li", content = function () 20.113 + ui.link { 20.114 + module = "delegation", view = "show", params = { 20.115 + area_id = area.id 20.116 + }, 20.117 + content = _"choose subject area delegatee" 20.118 + } 20.119 + end } 20.120 + elseif area.delegation_info.own_delegation_scope == "area" then 20.121 + ui.tag { tag = "li", content = function () 20.122 + ui.link { 20.123 + module = "delegation", view = "show", params = { 20.124 + area_id = area.id 20.125 + }, 20.126 + content = _"change/revoke area delegation" 20.127 + } 20.128 + end } 20.129 + else 20.130 + ui.tag { tag = "li", content = function () 20.131 + ui.link { 20.132 + module = "delegation", view = "show", params = { 20.133 + area_id = area.id 20.134 + }, 20.135 + content = _"change/revoke delegation only for this subject area" 20.136 + } 20.137 + end } 20.138 + end 20.139 + end } 20.140 + end ) 20.141 + 20.142 + 20.143 + 20.144 + 20.145 + if app.session.member:has_voting_right_for_unit_id ( area.unit_id ) then 20.146 + ui.sidebarSection ( function () 20.147 + ui.heading { 20.148 + level = 3, 20.149 + content = _("I want to start a new initiative", { 20.150 + area_name = area.name 20.151 + } ) 20.152 + } 20.153 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 20.154 + ui.tag { tag = "li", content = _"Take a look through the existing issues. Maybe someone else started a debate on your topic (and you can join it) or the topic has been decided already in the past." } 20.155 + ui.tag { tag = "li", content = function () 20.156 + ui.tag { content = function () 20.157 + ui.tag { content = _"If you cannot find any appropriate existing issue, " } 20.158 + ui.link { 20.159 + module = "initiative", view = "new", 20.160 + params = { area_id = area.id }, 20.161 + text = _"start an initiative in a new issue" 20.162 + } 20.163 + end } 20.164 + end } 20.165 + end } 20.166 + end ) 20.167 + end 20.168 + else 20.169 + end 20.170 + 20.171 +end ) 20.172 \ No newline at end of file
21.1 --- a/app/main/area/show.lua Thu Jul 10 01:02:43 2014 +0200 21.2 +++ b/app/main/area/show.lua Thu Jul 10 01:19:48 2014 +0200 21.3 @@ -1,27 +1,53 @@ 21.4 local area = Area:by_id(param.get_id()) 21.5 21.6 +if not area then 21.7 + execute.view { module = "index", view = "404" } 21.8 + request.set_status("404 Not Found") 21.9 + return 21.10 +end 21.11 + 21.12 +area:load_delegation_info_once_for_member_id(app.session.member_id) 21.13 21.14 app.html_title.title = area.name 21.15 app.html_title.subtitle = _("Area") 21.16 21.17 -util.help("area.show") 21.18 - 21.19 -slot.select("head", function() 21.20 - execute.view{ module = "area", view = "_head", params = { area = area, show_content = true, member = app.session.member } } 21.21 -end) 21.22 +execute.view { 21.23 + module = "area", view = "_head", params = { 21.24 + area = area, member = app.session.member 21.25 + } 21.26 +} 21.27 21.28 -ui.container{ 21.29 - attr = { class = "vertical"}, 21.30 - content = function() 21.31 - ui.field.text{ value = area.description } 21.32 - end 21.33 +execute.view { 21.34 + module = "area", view = "_sidebar_whatcanido", params = { 21.35 + area = area 21.36 + } 21.37 +} 21.38 + 21.39 +execute.view { 21.40 + module = "area", view = "_sidebar_members", params = { 21.41 + area = area 21.42 + } 21.43 } 21.44 21.45 -local open_issues_selector = area:get_reference_selector("issues") 21.46 - :add_where("issue.closed ISNULL") 21.47 - :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") 21.48 +function getOpenIssuesSelector() 21.49 + return area:get_reference_selector("issues") 21.50 + :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") 21.51 +end 21.52 + 21.53 +local admission_selector = getOpenIssuesSelector() 21.54 + :add_where("issue.state = 'admission'"); 21.55 21.56 -local closed_issues_selector = area:get_reference_selector("issues") 21.57 +local discussion_selector = getOpenIssuesSelector() 21.58 + :add_where("issue.state = 'discussion'"); 21.59 + 21.60 +local verification_selector = getOpenIssuesSelector() 21.61 + :add_where("issue.state = 'verification'"); 21.62 + 21.63 +local voting_selector = getOpenIssuesSelector() 21.64 + :add_where("issue.state = 'voting'"); 21.65 + 21.66 + 21.67 +local closed_selector = area:get_reference_selector("issues") 21.68 :add_where("issue.closed NOTNULL") 21.69 :add_order_by("issue.closed DESC") 21.70 21.71 @@ -30,61 +56,9 @@ 21.72 :join("member", "truster", "truster.id = delegation.truster_id AND truster.active") 21.73 :join("member", "trustee", "trustee.id = delegation.trustee_id AND trustee.active") 21.74 21.75 -local tabs = { 21.76 - module = "area", 21.77 - view = "show_tab", 21.78 - static_params = { area_id = area.id }, 21.79 -} 21.80 21.81 -tabs[#tabs+1] = { 21.82 - name = "timeline", 21.83 - label = _"Latest events", 21.84 - module = "event", 21.85 - view = "_list", 21.86 +execute.view { 21.87 + module = "issue", 21.88 + view = "_list2", 21.89 params = { for_area = area } 21.90 } 21.91 - 21.92 -tabs[#tabs+1] = { 21.93 - name = "open", 21.94 - label = _"Open issues", 21.95 - module = "issue", 21.96 - view = "_list", 21.97 - params = { 21.98 - for_state = "open", 21.99 - issues_selector = open_issues_selector, for_area = true 21.100 - } 21.101 -} 21.102 -tabs[#tabs+1] = { 21.103 - name = "closed", 21.104 - label = _"Closed issues", 21.105 - module = "issue", 21.106 - view = "_list", 21.107 - params = { 21.108 - for_state = "closed", 21.109 - issues_selector = closed_issues_selector, for_area = true 21.110 - } 21.111 -} 21.112 - 21.113 -if app.session:has_access("all_pseudonymous") then 21.114 - tabs[#tabs+1] = 21.115 - { 21.116 - name = "members", 21.117 - label = _"Participants" .. " (" .. tostring(members_selector:count()) .. ")", 21.118 - icon = { static = "icons/16/group.png" }, 21.119 - module = "member", 21.120 - view = "_list", 21.121 - params = { members_selector = members_selector } 21.122 - } 21.123 - 21.124 - tabs[#tabs+1] = 21.125 - { 21.126 - name = "delegations", 21.127 - label = _"Delegations" .. " (" .. tostring(delegations_selector:count()) .. ")", 21.128 - icon = { static = "icons/16/table_go.png" }, 21.129 - module = "delegation", 21.130 - view = "_list", 21.131 - params = { delegations_selector = delegations_selector } 21.132 - } 21.133 -end 21.134 - 21.135 -ui.tabs(tabs)
22.1 --- a/app/main/contact/list.lua Thu Jul 10 01:02:43 2014 +0200 22.2 +++ b/app/main/contact/list.lua Thu Jul 10 01:19:48 2014 +0200 22.3 @@ -6,9 +6,6 @@ 22.4 ui.title(_"Contacts") 22.5 22.6 22.7 -util.help("contact.list") 22.8 - 22.9 - 22.10 ui.paginate{ 22.11 selector = contacts_selector, 22.12 content = function()
23.1 --- a/app/main/delegation/_info.lua Thu Jul 10 01:02:43 2014 +0200 23.2 +++ b/app/main/delegation/_info.lua Thu Jul 10 01:19:48 2014 +0200 23.3 @@ -8,6 +8,8 @@ 23.4 local area = param.get("area", "table") 23.5 local issue = param.get("issue", "table") 23.6 23.7 +local for_title = param.get("for_title", "boolean") 23.8 + 23.9 local unit_id = unit and unit.id or nil 23.10 local area_id = area and area.id or nil 23.11 local issue_id = issue and issue.id or nil 23.12 @@ -21,7 +23,6 @@ 23.13 end 23.14 23.15 if area then 23.16 - area:load_delegation_info_once_for_member_id(member.id) 23.17 info = area.delegation_info 23.18 delegation_text = _"Delegate area" 23.19 end 23.20 @@ -31,24 +32,13 @@ 23.21 delegation_text = _"Delegate issue" 23.22 end 23.23 23.24 +if not info then 23.25 + --return 23.26 +end 23.27 + 23.28 local function print_delegation_info() 23.29 - local participant_occured = false 23.30 + local participant_occured = info.own_participation 23.31 23.32 - if info.own_participation or info.first_trustee_id then 23.33 - 23.34 - local class = "micro_avatar" 23.35 - if info.own_participation then 23.36 - participant_occured = true 23.37 - class = class .. " highlighted" 23.38 - end 23.39 - 23.40 - execute.view{ module = "member_image", view = "_show", params = { 23.41 - member = member, class = class, popup_text = member.name, 23.42 - image_type = "avatar", show_dummy = true, 23.43 - } } 23.44 - 23.45 - end 23.46 - 23.47 if not (issue and issue.state == "voting" and info.own_participation) then 23.48 23.49 if info.first_trustee_id then 23.50 @@ -154,10 +144,15 @@ 23.51 static = "delegation_arrow_24_horizontal.png" 23.52 } 23.53 23.54 - execute.view{ module = "member_image", view = "_show", params = { 23.55 - member_id = info.first_trustee_id, class = "micro_avatar", popup_text = info.first_trustee_name, 23.56 - image_type = "avatar", show_dummy = true, 23.57 - } } 23.58 + execute.view{ 23.59 + module = "member_image", view = "_show", params = { 23.60 + member_id = info.first_trustee_id, 23.61 + class = "micro_avatar", 23.62 + popup_text = info.first_trustee_name, 23.63 + image_type = "avatar", 23.64 + show_dummy = true, 23.65 + } 23.66 + } 23.67 end 23.68 23.69 23.70 @@ -174,24 +169,94 @@ 23.71 end 23.72 end 23.73 23.74 +if not param.get("no_star", "boolean") then 23.75 + 23.76 + if info.own_participation then 23.77 + if issue and issue.fully_frozen then 23.78 + ui.link{ 23.79 + attr = { class = "right" }, 23.80 + module = "vote", view = "list", params = { 23.81 + issue_id = issue.id 23.82 + }, 23.83 + content = function () 23.84 + ui.tag { content = _"you voted" } 23.85 + end 23.86 + } 23.87 + else 23.88 + if issue then 23.89 + local text = _"you are interested" 23.90 + ui.image { attr = { class = "star", title = text, alt = text }, static = "icons/48/eye.png" } 23.91 + if not issue.closed and info.own_participation and info.weight and info.weight > 1 then 23.92 + ui.link { 23.93 + attr = { class = "right" }, content = "+" .. (info.weight - 1), 23.94 + module = "delegation", view = "show_incoming", params = { 23.95 + issue_id = issue.id, member_id = member.id 23.96 + } 23.97 + } 23.98 + end 23.99 + else 23.100 + local text = _"you are subscribed" 23.101 + ui.image { attr = { class = "icon24 star", title = text, alt = text }, static = "icons/48/star.png" } 23.102 + end 23.103 + if not for_title then 23.104 + slot.put("<br />") 23.105 + else 23.106 + slot.put(" ") 23.107 + end 23.108 + end 23.109 + end 23.110 +end 23.111 + 23.112 23.113 if info.own_participation or info.first_trustee_id then 23.114 + local class = "delegation_info" 23.115 + if info.own_participation then 23.116 + class = class .. " suspended" 23.117 + end 23.118 + 23.119 + local voting_member_id 23.120 + local voting_member_name 23.121 + if issue and issue.fully_frozen and issue.closed then 23.122 + if issue.member_info.first_trustee_participation then 23.123 + voting_member_id = issue.member_info.first_trustee_id 23.124 + voting_member_name = issue.member_info.first_trustee_name 23.125 + elseif issue.member_info.other_trustee_participation then 23.126 + voting_member_id = issue.member_info.other_trustee_id 23.127 + voting_member_name = issue.member_info.other_trustee_name 23.128 + end 23.129 + end 23.130 + 23.131 if app.session.member_id == member.id then 23.132 - ui.link{ 23.133 - module = "delegation", view = "show", params = { 23.134 - unit_id = unit_id, 23.135 - area_id = area_id, 23.136 - issue_id = issue_id 23.137 - }, 23.138 - attr = { class = "delegation_info" }, content = function() 23.139 - print_delegation_info() 23.140 - end 23.141 - } 23.142 + 23.143 + if voting_member_id then 23.144 + ui.link{ 23.145 + module = "vote", view = "list", params = { 23.146 + issue_id = issue.id, 23.147 + member_id = voting_member_id 23.148 + }, 23.149 + attr = { class = class }, content = function() 23.150 + print_delegation_info() 23.151 + end 23.152 + } 23.153 + 23.154 + else 23.155 + ui.link{ 23.156 + module = "delegation", view = "show", params = { 23.157 + unit_id = unit_id, 23.158 + area_id = area_id, 23.159 + issue_id = issue_id 23.160 + }, 23.161 + attr = { class = class }, content = function() 23.162 + print_delegation_info() 23.163 + end 23.164 + } 23.165 + end 23.166 else 23.167 ui.container{ 23.168 - attr = { class = "delegation_info" }, content = function() 23.169 + attr = { class = class }, content = function() 23.170 print_delegation_info() 23.171 end 23.172 } 23.173 end 23.174 end 23.175 +
24.1 --- a/app/main/delegation/_list.lua Thu Jul 10 01:02:43 2014 +0200 24.2 +++ b/app/main/delegation/_list.lua Thu Jul 10 01:19:48 2014 +0200 24.3 @@ -3,83 +3,84 @@ 24.4 local incoming = param.get("incoming", atom.boolean) 24.5 24.6 local function delegation_scope(delegation) 24.7 - ui.container{ 24.8 + ui.tag{ 24.9 attr = { class = "delegation_scope" }, 24.10 content = function() 24.11 local area 24.12 local unit 24.13 if delegation.issue then 24.14 area = delegation.issue.area 24.15 + unit = area.unit 24.16 elseif delegation.area then 24.17 area = delegation.area 24.18 + unit = area.unit 24.19 else 24.20 unit = delegation.unit 24.21 end 24.22 - if unit then 24.23 + slot.put("<br style='clear: left;' />") 24.24 + ui.heading { attr = { style = "float: left;" }, level = 3, content = function() 24.25 ui.link{ 24.26 - content = _"Unit '#{name}'":gsub("#{name}", unit.name), 24.27 + content = unit.name, 24.28 module = "unit", 24.29 view = "show", 24.30 id = unit.id 24.31 } 24.32 - end 24.33 - if area then 24.34 - ui.link{ 24.35 - content = _"Area '#{name}'":gsub("#{name}", area.name), 24.36 - module = "area", 24.37 - view = "show", 24.38 - id = area.id 24.39 - } 24.40 - end 24.41 - if delegation.issue then 24.42 - ui.link{ 24.43 - content = _"Issue ##{id}":gsub("#{id}", delegation.issue.id), 24.44 - module = "issue", 24.45 - view = "show", 24.46 - id = delegation.issue.id 24.47 - } 24.48 - end 24.49 + if area then 24.50 + slot.put(" · ") 24.51 + ui.link{ 24.52 + content = area.name, 24.53 + module = "area", 24.54 + view = "show", 24.55 + id = area.id 24.56 + } 24.57 + end 24.58 + if delegation.issue then 24.59 + slot.put(" · ") 24.60 + ui.link{ 24.61 + content = delegation.issue.name, 24.62 + module = "issue", 24.63 + view = "show", 24.64 + id = delegation.issue.id 24.65 + } 24.66 + end 24.67 + end } 24.68 end 24.69 } 24.70 end 24.71 24.72 24.73 -ui.paginate{ 24.74 - selector = delegations_selector, 24.75 - content = function() 24.76 +--ui.paginate{ 24.77 +-- selector = delegations_selector, 24.78 +-- name = incoming and "delegation_incoming" or "delegation_outgoing", 24.79 +-- content = function() 24.80 + local last_scope = {} 24.81 for i, delegation in ipairs(delegations_selector:exec()) do 24.82 - ui.container{ 24.83 - attr = { class = "delegation_list_entry" }, 24.84 - content = function() 24.85 - if outgoing then 24.86 - delegation_scope(delegation) 24.87 - else 24.88 - execute.view{ 24.89 - module = "member", 24.90 - view = "_show_thumb", 24.91 - params = { member = delegation.truster } 24.92 - } 24.93 - end 24.94 - ui.image{ 24.95 - attr = { class = "delegation_arrow" }, 24.96 - static = "delegation_arrow.jpg" 24.97 - } 24.98 - if incoming then 24.99 - delegation_scope(delegation) 24.100 - else 24.101 - if delegation.trustee then 24.102 - execute.view{ 24.103 - module = "member", 24.104 - view = "_show_thumb", 24.105 - params = { member = delegation.trustee } 24.106 - } 24.107 - else 24.108 - ui.tag{ content = _"Delegation abandoned" } 24.109 - end 24.110 - end 24.111 - end 24.112 - } 24.113 + if last_scope.unit_id ~= delegation.unit_id 24.114 + or last_scope.area_id ~= delegation.area_id 24.115 + or last_scope.issue_id ~= delegation.issue_id 24.116 + then 24.117 + last_scope.unit_id = delegation.unit_id 24.118 + last_scope.area_id = delegation.area_id 24.119 + last_scope.issue_id = delegation.issue_id 24.120 + delegation_scope(delegation) 24.121 + end 24.122 + if incoming then 24.123 + execute.view{ module = "member_image", view = "_show", params = { 24.124 + member_id = delegation.truster_id, class = "micro_avatar", popup_text = delegation.truster.name, 24.125 + image_type = "avatar", show_dummy = true, 24.126 + } } 24.127 + elseif delegation.trustee then 24.128 + ui.image{ 24.129 + attr = { class = "delegation_arrow" }, 24.130 + static = "delegation_arrow_24_horizontal.png" 24.131 + } 24.132 + execute.view{ module = "member_image", view = "_show", params = { 24.133 + member_id = delegation.trustee_id, class = "micro_avatar", popup_text = delegation.trustee.name, 24.134 + image_type = "avatar", show_dummy = true, 24.135 + } } 24.136 + else 24.137 + ui.tag{ content = _"Delegation abandoned" } 24.138 + end 24.139 end 24.140 - slot.put("<br style='clear: left;' />") 24.141 - end 24.142 -} 24.143 +-- end 24.144 +--}
25.1 --- a/app/main/delegation/show.lua Thu Jul 10 01:02:43 2014 +0200 25.2 +++ b/app/main/delegation/show.lua Thu Jul 10 01:19:48 2014 +0200 25.3 @@ -2,7 +2,17 @@ 25.4 local current_trustee_id 25.5 local current_trustee_name 25.6 25.7 +local head_text 25.8 + 25.9 local unit = Unit:by_id(param.get("unit_id", atom.integer)) 25.10 +local area = Area:by_id(param.get("area_id", atom.integer)) 25.11 +local issue = Issue:by_id(param.get("issue_id", atom.integer)) 25.12 +local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) 25.13 + 25.14 +if initiative then 25.15 + issue = initiative.issue 25.16 +end 25.17 + 25.18 if unit then 25.19 unit:load_delegation_info_once_for_member_id(app.session.member_id) 25.20 voting_right_unit_id = unit.id 25.21 @@ -10,11 +20,10 @@ 25.22 current_trustee_id = unit.delegation_info.first_trustee_id 25.23 current_trustee_name = unit.delegation_info.first_trustee_name 25.24 end 25.25 - ui.title(config.single_unit_id and _"Set global delegation" or _"Set unit delegation") 25.26 - util.help("delegation.new.unit") 25.27 + execute.view { module = "unit", view = "_head", params = { unit = unit } } 25.28 + head_text = _"Set unit delegation" 25.29 end 25.30 25.31 -local area = Area:by_id(param.get("area_id", atom.integer)) 25.32 if area then 25.33 area:load_delegation_info_once_for_member_id(app.session.member_id) 25.34 voting_right_unit_id = area.unit_id 25.35 @@ -22,11 +31,10 @@ 25.36 current_trustee_id = area.delegation_info.first_trustee_id 25.37 current_trustee_name = area.delegation_info.first_trustee_name 25.38 end 25.39 - ui.title(_"Set delegation for Area '#{name}'":gsub("#{name}", area.name)) 25.40 - util.help("delegation.new.area") 25.41 + execute.view { module = "area", view = "_head", params = { area = area } } 25.42 + head_text = _"Set area delegation" 25.43 end 25.44 25.45 -local issue = Issue:by_id(param.get("issue_id", atom.integer)) 25.46 if issue then 25.47 issue:load("member_info", { member_id = app.session.member_id }) 25.48 voting_right_unit_id = issue.area.unit_id 25.49 @@ -34,8 +42,13 @@ 25.50 current_trustee_id = issue.member_info.first_trustee_id 25.51 current_trustee_name = issue.member_info.first_trustee_name 25.52 end 25.53 - ui.title(_"Set delegation for Issue ##{number} in Area '#{area_name}'":gsub("#{number}", issue.id):gsub("#{area_name}", issue.area.name)) 25.54 - util.help("delegation.new.issue") 25.55 + execute.view { module = "issue", view = "_head", params = { issue = issue } } 25.56 + head_text = _"Set issue delegation" 25.57 +end 25.58 + 25.59 +if param.get("initiative_id", atom.integer) then 25.60 + issue_id = initiative.issue_id 25.61 + scope = "issue" 25.62 end 25.63 25.64 25.65 @@ -44,17 +57,16 @@ 25.66 local area_id 25.67 local issue_id 25.68 local initiative_id 25.69 -local initiative 25.70 25.71 local scope = "unit" 25.72 25.73 +local inline = param.get("inline", atom.boolean) 25.74 + 25.75 + 25.76 unit_id = param.get("unit_id", atom.integer) 25.77 25.78 -local inline = param.get("inline", atom.boolean) 25.79 - 25.80 if param.get("initiative_id", atom.integer) then 25.81 - initiative_id = param.get("initiative_id", atom.integer) 25.82 - initiative = Initiative:by_id(initiative_id) 25.83 + initiative_id = initiative.id 25.84 issue_id = initiative.issue_id 25.85 scope = "issue" 25.86 end 25.87 @@ -106,177 +118,204 @@ 25.88 25.89 ui.script{ static = "js/update_delegation_info.js" } 25.90 25.91 -ui.actions(function() 25.92 - if issue then 25.93 - ui.link{ 25.94 - module = "issue", 25.95 - view = "show", 25.96 - id = issue.id, 25.97 - content = function() 25.98 - ui.image{ static = "icons/16/cancel.png" } 25.99 - slot.put(_"Cancel") 25.100 - end, 25.101 - } 25.102 - elseif area then 25.103 - ui.link{ 25.104 - module = "area", 25.105 - view = "show", 25.106 - id = area.id, 25.107 - content = function() 25.108 - ui.image{ static = "icons/16/cancel.png" } 25.109 - slot.put(_"Cancel") 25.110 - end, 25.111 - } 25.112 - else 25.113 - ui.link{ 25.114 - module = "index", 25.115 - view = "index", 25.116 - content = function() 25.117 - ui.image{ static = "icons/16/cancel.png" } 25.118 - slot.put(_"Cancel") 25.119 - end, 25.120 - } 25.121 - end 25.122 -end) 25.123 + 25.124 +ui.section( function () 25.125 + 25.126 + ui.sectionHead( function () 25.127 + ui.heading{ level = 1, content = head_text } 25.128 + end ) 25.129 + 25.130 + ui.sectionRow( function () 25.131 25.132 - 25.133 -ui.form{ 25.134 - attr = { class = "vertical", id = "delegationForm" }, 25.135 - module = "delegation", 25.136 - action = "update", 25.137 - params = { 25.138 - unit_id = unit and unit.id or nil, 25.139 - area_id = area and area.id or nil, 25.140 - issue_id = issue and issue.id or nil, 25.141 - initiative_id = initiative_id 25.142 - }, 25.143 - routing = { 25.144 - default = { 25.145 - mode = "redirect", 25.146 - module = area and "area" or initiative and "initiative" or issue and "issue" or "unit", 25.147 - view = "show", 25.148 - id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id, 25.149 - } 25.150 - }, 25.151 - content = function() 25.152 - local records 25.153 - 25.154 - if issue then 25.155 - local delegate_name = "" 25.156 - local scope = "no delegation set" 25.157 - local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id) 25.158 - if area_delegation then 25.159 - delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned" 25.160 - scope = _"area" 25.161 - else 25.162 - local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id) 25.163 + ui.form{ 25.164 + attr = { class = "wide section", id = "delegationForm" }, 25.165 + module = "delegation", 25.166 + action = "update", 25.167 + params = { 25.168 + unit_id = unit and unit.id or nil, 25.169 + area_id = area and area.id or nil, 25.170 + issue_id = issue and issue.id or nil, 25.171 + initiative_id = initiative_id 25.172 + }, 25.173 + routing = { 25.174 + default = { 25.175 + mode = "redirect", 25.176 + module = area and "area" or initiative and "initiative" or issue and "issue" or "unit", 25.177 + view = "show", 25.178 + id = area and area.id or initiative and initiative.id or issue and issue.id or unit.id, 25.179 + } 25.180 + }, 25.181 + content = function() 25.182 + local record 25.183 + if issue then 25.184 + local delegate_name = "" 25.185 + local scope = "no delegation set" 25.186 + local area_delegation = Delegation:by_pk(app.session.member_id, nil, issue.area_id) 25.187 + if area_delegation then 25.188 + delegate_name = area_delegation.trustee and area_delegation.trustee.name or _"abandoned" 25.189 + scope = _"area" 25.190 + else 25.191 + local unit_delegation = Delegation:by_pk(app.session.member_id, issue.area.unit_id) 25.192 + if unit_delegation then 25.193 + delegate_name = unit_delegation.trustee.name 25.194 + scope = config.single_unit_id and _"global" or _"unit" 25.195 + end 25.196 + end 25.197 + local text_apply 25.198 + local text_abandon 25.199 + if config.single_unit_id then 25.200 + text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.201 + text_abandon = _"Abandon unit and area delegations for this issue" 25.202 + else 25.203 + text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.204 + text_abandon = _"Abandon unit and area delegations for this issue" 25.205 + end 25.206 + 25.207 + records = { 25.208 + { id = -1, name = text_apply }, 25.209 + { id = 0, name = text_abandon } 25.210 + } 25.211 + elseif area then 25.212 + local delegate_name = "" 25.213 + local scope = "no delegation set" 25.214 + local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id) 25.215 if unit_delegation then 25.216 delegate_name = unit_delegation.trustee.name 25.217 scope = config.single_unit_id and _"global" or _"unit" 25.218 end 25.219 - end 25.220 - local text_apply 25.221 - local text_abandon 25.222 - if config.single_unit_id then 25.223 - text_apply = _("Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.224 - text_abandon = _"Abandon unit and area delegations for this issue" 25.225 + local text_apply 25.226 + local text_abandon 25.227 + if config.single_unit_id then 25.228 + text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.229 + text_abandon = _"Abandon global delegation for this area" 25.230 + else 25.231 + text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.232 + text_abandon = _"Abandon unit delegation for this area" 25.233 + end 25.234 + records = { 25.235 + { 25.236 + id = -1, 25.237 + name = text_apply 25.238 + }, 25.239 + { 25.240 + id = 0, 25.241 + name = text_abandon 25.242 + } 25.243 + } 25.244 + 25.245 else 25.246 - text_apply = _("Apply unit or area delegation for this issue (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.247 - text_abandon = _"Abandon unit and area delegations for this issue" 25.248 + records = { 25.249 + { 25.250 + id = -1, 25.251 + name = _"No delegation" 25.252 + } 25.253 + } 25.254 + 25.255 end 25.256 - records = { 25.257 - { id = -1, name = text_apply }, 25.258 - { id = 0, name = text_abandon } 25.259 - } 25.260 - elseif area then 25.261 - local delegate_name = "" 25.262 - local scope = "no delegation set" 25.263 - local unit_delegation = Delegation:by_pk(app.session.member_id, area.unit_id) 25.264 - if unit_delegation then 25.265 - delegate_name = unit_delegation.trustee.name 25.266 - scope = config.single_unit_id and _"global" or _"unit" 25.267 + -- add current trustee 25.268 + if current_trustee_id then 25.269 + records[#records+1] = {id="_", name= "--- " .. _"Current delegatee" .. " ---"} 25.270 + records[#records+1] = { id = current_trustee_id, name = current_trustee_name } 25.271 + end 25.272 + -- add initiative authors 25.273 + if initiative then 25.274 + records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"} 25.275 + for i,record in ipairs(initiative.initiators) do 25.276 + records[#records+1] = record.member 25.277 + end 25.278 + end 25.279 + -- add saved members 25.280 + if #contact_members > 0 then 25.281 + records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"} 25.282 + for i, record in ipairs(contact_members) do 25.283 + records[#records+1] = record 25.284 + end 25.285 + end 25.286 + 25.287 + disabled_records = {} 25.288 + disabled_records["_"] = true 25.289 + disabled_records[app.session.member_id] = true 25.290 + 25.291 + local value = current_trustee_id 25.292 + if preview_trustee_id then 25.293 + value = preview_trustee_id 25.294 + end 25.295 + if preview_trustee_id == nil and delegation and not delegation.trustee_id then 25.296 + value = 0 25.297 end 25.298 - local text_apply 25.299 - local text_abandon 25.300 - if config.single_unit_id then 25.301 - text_apply = _("Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.302 - text_abandon = _"Abandon global delegation for this area" 25.303 + 25.304 + ui.heading{ level = 2, content = _"Choose your delegatee" } 25.305 + 25.306 + ui.field.select{ 25.307 + attr = { onchange = "updateDelegationInfo();" }, 25.308 + name = "trustee_id", 25.309 + foreign_records = records, 25.310 + foreign_id = "id", 25.311 + foreign_name = "name", 25.312 + disabled_records = disabled_records, 25.313 + value = value 25.314 + } 25.315 + 25.316 + ui.container{ content = _"You can choose only members which you have been saved as contact before." } 25.317 + 25.318 + ui.field.hidden{ name = "preview" } 25.319 + 25.320 + slot.put("<br />") 25.321 + ui.tag { tag = "input", content = "", attr = { 25.322 + type = "submit", 25.323 + value = _"Save", 25.324 + class = "btn btn-default", 25.325 + } } 25.326 + 25.327 + slot.put("<br /><br /><br />") 25.328 + if initiative then 25.329 + ui.link{ 25.330 + module = "initiative", 25.331 + view = "show", 25.332 + id = initiative.id, 25.333 + content = function() 25.334 + slot.put(_"Cancel") 25.335 + end, 25.336 + } 25.337 + elseif issue then 25.338 + ui.link{ 25.339 + module = "issue", 25.340 + view = "show", 25.341 + id = issue.id, 25.342 + content = function() 25.343 + slot.put(_"Cancel") 25.344 + end, 25.345 + } 25.346 + elseif area then 25.347 + ui.link{ 25.348 + module = "area", 25.349 + view = "show", 25.350 + id = area.id, 25.351 + content = function() 25.352 + slot.put(_"Cancel") 25.353 + end, 25.354 + } 25.355 else 25.356 - text_apply = _("Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])", { delegate_name = delegate_name, scope = scope }) 25.357 - text_abandon = _"Abandon unit delegation for this area" 25.358 + ui.link{ 25.359 + module = "index", 25.360 + view = "index", 25.361 + content = function() 25.362 + slot.put(_"Cancel") 25.363 + end, 25.364 + } 25.365 end 25.366 - records = { 25.367 - { 25.368 - id = -1, 25.369 - name = text_apply 25.370 - }, 25.371 - { 25.372 - id = 0, 25.373 - name = text_abandon 25.374 - } 25.375 - } 25.376 - 25.377 - else 25.378 - records = { 25.379 - { 25.380 - id = -1, 25.381 - name = _"No delegation" 25.382 - } 25.383 - } 25.384 25.385 end 25.386 - -- add current trustee 25.387 - if current_trustee_id then 25.388 - records[#records+1] = {id="_", name= "--- " .. _"Current trustee" .. " ---"} 25.389 - records[#records+1] = { id = current_trustee_id, name = current_trustee_name } 25.390 - end 25.391 - -- add initiative authors 25.392 - if initiative then 25.393 - records[#records+1] = {id="_", name= "--- " .. _"Initiators" .. " ---"} 25.394 - for i,record in ipairs(initiative.initiators) do 25.395 - records[#records+1] = record.member 25.396 - end 25.397 - end 25.398 - -- add saved members 25.399 - if #contact_members > 0 then 25.400 - records[#records+1] = {id="_", name= "--- " .. _"Saved contacts" .. " ---"} 25.401 - for i, record in ipairs(contact_members) do 25.402 - records[#records+1] = record 25.403 - end 25.404 - end 25.405 + } 25.406 25.407 - disabled_records = {} 25.408 - disabled_records["_"] = true 25.409 - disabled_records[app.session.member_id] = true 25.410 +end ) end ) 25.411 +-- ------------------------ 25.412 25.413 - local value = current_trustee_id 25.414 - if preview_trustee_id then 25.415 - value = preview_trustee_id 25.416 - end 25.417 - if preview_trustee_id == nil and delegation and not delegation.trustee_id then 25.418 - value = 0 25.419 - end 25.420 - 25.421 - ui.field.select{ 25.422 - attr = { onchange = "updateDelegationInfo();" }, 25.423 - label = _"Trustee", 25.424 - name = "trustee_id", 25.425 - foreign_records = records, 25.426 - foreign_id = "id", 25.427 - foreign_name = "name", 25.428 - disabled_records = disabled_records, 25.429 - value = value 25.430 - } 25.431 +ui.sidebar( "tab-members", function () 25.432 25.433 - ui.field.hidden{ name = "preview" } 25.434 - 25.435 - ui.submit{ text = _"Save" } 25.436 - 25.437 - end 25.438 -} 25.439 - 25.440 - 25.441 --- ------------------------ 25.442 +ui.sidebarHead( function () 25.443 + ui.heading { level = 1, content = _"Preview of delegation" } 25.444 +end ) 25.445 25.446 local preview_inherit = false 25.447 local tmp_preview_trustee_id = preview_trustee_id 25.448 @@ -293,50 +332,58 @@ 25.449 for i, record in ipairs(delegation_chain) do 25.450 local style 25.451 local overridden = (not issue or issue.state ~= 'voting') and record.overridden 25.452 - if record.scope_in then 25.453 - if not overridden then 25.454 - ui.image{ 25.455 - attr = { class = "delegation_arrow" }, 25.456 - static = "delegation_arrow_24_vertical.png" 25.457 - } 25.458 - else 25.459 - ui.image{ 25.460 - attr = { class = "delegation_arrow delegation_arrow_overridden" }, 25.461 - static = "delegation_arrow_24_vertical.png" 25.462 + ui.sidebarSection( function () 25.463 + if record.scope_in then 25.464 + if not overridden then 25.465 + local text = _"delegated to" 25.466 + ui.image{ 25.467 + attr = { class = "delegation_arrow", alt = text, title = text }, 25.468 + static = "delegation_arrow_24_vertical.png" 25.469 + } 25.470 + else 25.471 + local text = _"delegated to" 25.472 + ui.image{ 25.473 + attr = { class = "delegation_arrow delegation_arrow_overridden", alt = text, title = text }, 25.474 + static = "delegation_arrow_24_vertical.png" 25.475 + } 25.476 + end 25.477 + ui.tag{ 25.478 + attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") }, 25.479 + content = function() 25.480 + if record.scope_in == "unit" then 25.481 + slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation") 25.482 + elseif record.scope_in == "area" then 25.483 + slot.put(_"Area delegation") 25.484 + elseif record.scope_in == "issue" then 25.485 + slot.put(_"Issue delegation") 25.486 + end 25.487 + end 25.488 } 25.489 end 25.490 - ui.tag{ 25.491 - attr = { class = "delegation_scope" .. (overridden and " delegation_scope_overridden" or "") }, 25.492 + ui.container{ 25.493 + attr = { class = overridden and "delegation_overridden" or "" }, 25.494 content = function() 25.495 - if record.scope_in == "unit" then 25.496 - slot.put(config.single_object_mode and _"Global delegation" or _"Unit delegation") 25.497 - elseif record.scope_in == "area" then 25.498 - slot.put(_"Area delegation") 25.499 - elseif record.scope_in == "issue" then 25.500 - slot.put(_"Issue delegation") 25.501 - end 25.502 + execute.view{ 25.503 + module = "member", 25.504 + view = "_show_thumb", 25.505 + params = { member = record } 25.506 + } 25.507 end 25.508 } 25.509 - end 25.510 - ui.container{ 25.511 - attr = { class = overridden and "delegation_overridden" or "" }, 25.512 - content = function() 25.513 - execute.view{ 25.514 - module = "member", 25.515 - view = "_show_thumb", 25.516 - params = { member = record } 25.517 + if issue and issue.state ~= 'voting' and record.participation and not record.overridden then 25.518 + ui.container{ 25.519 + attr = { class = "delegation_participation" }, 25.520 + content = function() 25.521 + if i == #delegation_chain then 25.522 + ui.tag{ content = _"This member is currently participating in this issue." } 25.523 + else 25.524 + ui.tag{ content = _"This member is participating, the remaining delegation chain is suspended during discussing." } 25.525 + end 25.526 + end 25.527 } 25.528 end 25.529 - } 25.530 - if (not issue or issue.state ~= 'voting') and record.participation and not record.overridden then 25.531 - ui.container{ 25.532 - attr = { class = "delegation_participation" }, 25.533 - content = function() 25.534 - slot.put(_"This member is participating, the rest of delegation chain is suspended while discussing") 25.535 - end 25.536 - } 25.537 - end 25.538 - slot.put("<br style='clear: left'/>") 25.539 + slot.put("<br style='clear: left'/>") 25.540 + end ) 25.541 end 25.542 25.543 if preview_trustee_id == 0 or not preview_trustee_id == null and delegation and not delegation.trustee_id then 25.544 @@ -350,3 +397,5 @@ 25.545 end 25.546 end 25.547 25.548 + 25.549 +end ) 25.550 \ No newline at end of file
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/app/main/delegation/show_incoming.lua Thu Jul 10 01:19:48 2014 +0200 26.3 @@ -0,0 +1,35 @@ 26.4 +local issue = Issue:by_id(param.get("issue_id", atom.integer)) 26.5 + 26.6 +local member = Member:by_id(param.get("member_id", atom.integer)) 26.7 + 26.8 +local members_selector = Member:new_selector() 26.9 + :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id") 26.10 + :join("issue", nil, "issue.id = delegating_interest_snapshot.issue_id") 26.11 + :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id } 26.12 + :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event } 26.13 + :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id } 26.14 + :add_field{ "delegating_interest_snapshot.weight" } 26.15 + 26.16 + 26.17 +execute.view { 26.18 + module = "issue", view = "_head", params = { 26.19 + issue = issue 26.20 + } 26.21 +} 26.22 + 26.23 +ui.section( function() 26.24 + 26.25 + ui.sectionHead( function() 26.26 + ui.heading{ level = 1, content = _("Incoming delegations for '#{member_name}'", { member_name = member.name } ) } 26.27 + end) 26.28 + 26.29 + execute.view{ 26.30 + module = "member", 26.31 + view = "_list", 26.32 + params = { 26.33 + members_selector = members_selector, 26.34 + issue = issue, 26.35 + trustee = member 26.36 + } 26.37 + } 26.38 +end ) 26.39 \ No newline at end of file
27.1 --- a/app/main/draft/_action/add.lua Thu Jul 10 01:02:43 2014 +0200 27.2 +++ b/app/main/draft/_action/add.lua Thu Jul 10 01:19:48 2014 +0200 27.3 @@ -25,19 +25,24 @@ 27.4 return false 27.5 end 27.6 27.7 -local formatting_engine = param.get("formatting_engine") 27.8 +local formatting_engine 27.9 +if config.enforce_formatting_engine then 27.10 + formatting_engine = config.enforce_formatting_engine 27.11 +else 27.12 + formatting_engine = param.get("formatting_engine") 27.13 27.14 -local formatting_engine_valid = false 27.15 -for fe, dummy in pairs(config.formatting_engine_executeables) do 27.16 - if formatting_engine == fe then 27.17 - formatting_engine_valid = true 27.18 + local formatting_engine_valid = false 27.19 + for i, fe in pairs(config.formatting_engines) do 27.20 + if formatting_engine == fe.id then 27.21 + formatting_engine_valid = true 27.22 + end 27.23 + end 27.24 + if not formatting_engine_valid then 27.25 + error("invalid formatting engine!") 27.26 end 27.27 end 27.28 -if not formatting_engine_valid then 27.29 - error("invalid formatting engine!") 27.30 -end 27.31 27.32 -if param.get("preview") then 27.33 +if param.get("preview") or param.get("edit") then 27.34 return false 27.35 end 27.36 27.37 @@ -57,5 +62,5 @@ 27.38 27.39 draft:render_content() 27.40 27.41 -slot.put_into("notice", _"New draft has been added to initiative") 27.42 +slot.put_into("notice", _"The initiative text has been updated") 27.43
28.1 --- a/app/main/draft/diff.lua Thu Jul 10 01:02:43 2014 +0200 28.2 +++ b/app/main/draft/diff.lua Thu Jul 10 01:19:48 2014 +0200 28.3 @@ -1,13 +1,20 @@ 28.4 local old_draft_id = param.get("old_draft_id", atom.integer) 28.5 local new_draft_id = param.get("new_draft_id", atom.integer) 28.6 +local initiative_id = param.get("initiative_id", atom.number) 28.7 28.8 -if not old_draft_id or not new_draft_id then 28.9 - slot.put( _"Please choose two versions of the draft to compare") 28.10 - return 28.11 -end 28.12 - 28.13 -if old_draft_id == new_draft_id then 28.14 - slot.put( _"Please choose two different versions of the draft to compare") 28.15 +if not old_draft_id 28.16 + or not new_draft_id 28.17 + or old_draft_id == new_draft_id 28.18 +then 28.19 + slot.reset_all() 28.20 + slot.select("error", function() 28.21 + ui.tag{ content = _"Please choose two different versions of the draft to compare" } 28.22 + end ) 28.23 + request.redirect{ 28.24 + module = "draft", view = "list", params = { 28.25 + initiative_id = initiative_id 28.26 + } 28.27 + } 28.28 return 28.29 end 28.30 28.31 @@ -20,40 +27,46 @@ 28.32 local old_draft = Draft:by_id(old_draft_id) 28.33 local new_draft = Draft:by_id(new_draft_id) 28.34 28.35 -execute.view{ 28.36 - module = "draft", 28.37 - view = "_head", 28.38 - params = { draft = new_draft} 28.39 +local initiative = new_draft.initiative 28.40 + 28.41 +if app.session.member then 28.42 + initiative:load_everything_for_member_id(app.session.member_id) 28.43 + initiative.issue:load_everything_for_member_id(app.session.member_id) 28.44 +end 28.45 + 28.46 + 28.47 +execute.view{ module = "issue", view = "_sidebar_state", params = { 28.48 + initiative = initiative 28.49 +} } 28.50 + 28.51 +execute.view { 28.52 + module = "issue", view = "_sidebar_issue", 28.53 + params = { 28.54 + issue = initiative.issue, 28.55 + highlight_initiative_id = initiative.id 28.56 + } 28.57 } 28.58 28.59 -ui.title(_"Diff") 28.60 +execute.view { 28.61 + module = "issue", view = "_sidebar_whatcanido", 28.62 + params = { initiative = initiative } 28.63 +} 28.64 28.65 -if app.session.member_id and not new_draft.initiative.revoked then 28.66 - local supporter = Supporter:new_selector():add_where{"member_id = ?", app.session.member_id}:count() 28.67 - if supporter then 28.68 - ui.container{ 28.69 - attr = { class = "draft_updated_info" }, 28.70 - content = function() 28.71 - slot.put(_"The draft of this initiative has been updated!") 28.72 - slot.put(" ") 28.73 - ui.link{ 28.74 - text = _"Refresh support to current draft", 28.75 - module = "initiative", 28.76 - action = "add_support", 28.77 - id = new_draft.initiative.id, 28.78 - routing = { 28.79 - default = { 28.80 - mode = "redirect", 28.81 - module = "initiative", 28.82 - view = "show", 28.83 - id = new_draft.initiative.id 28.84 - } 28.85 - } 28.86 - } 28.87 - end 28.88 - } 28.89 - end 28.90 -end 28.91 +execute.view { 28.92 + module = "issue", view = "_sidebar_members", params = { 28.93 + issue = initiative.issue, initiative = initiative 28.94 + } 28.95 +} 28.96 + 28.97 + 28.98 + 28.99 +execute.view { 28.100 + module = "issue", view = "_head", params = { 28.101 + issue = initiative.issue 28.102 + } 28.103 +} 28.104 + 28.105 + 28.106 28.107 local old_draft_content = string.gsub(string.gsub(old_draft.content, "\n", " ###ENTER###\n"), " ", "\n") 28.108 local new_draft_content = string.gsub(string.gsub(new_draft.content, "\n", " ###ENTER###\n"), " ", "\n") 28.109 @@ -111,17 +124,87 @@ 28.110 end 28.111 end 28.112 28.113 -if not status then 28.114 - ui.field.text{ value = _"The drafts do not differ" } 28.115 -else 28.116 - ui.container{ 28.117 - tag = "div", 28.118 - attr = { class = "diff" }, 28.119 - content = function() 28.120 - output = output:gsub("[^\n\r]+", function(line) 28.121 - process_line(line) 28.122 - end) 28.123 +ui.section( function() 28.124 + ui.sectionHead( function() 28.125 + ui.link{ 28.126 + module = "initiative", view = "show", id = initiative.id, 28.127 + content = function () 28.128 + ui.heading { 28.129 + level = 1, 28.130 + content = initiative.display_name 28.131 + } 28.132 + end 28.133 + } 28.134 + ui.heading{ level = 2, content = _("Comparision of revisions #{id1} and #{id2}", { 28.135 + id1 = old_draft.id, 28.136 + id2 = new_draft.id 28.137 + } ) } 28.138 + end ) 28.139 + 28.140 + if app.session.member_id and not new_draft.initiative.revoked then 28.141 + local supporter = app.session.member:get_reference_selector("supporters") 28.142 + :add_where{ "initiative_id = ?", new_draft.initiative_id } 28.143 + :optional_object_mode() 28.144 + :exec() 28.145 + if supporter and supporter.draft_id ~= new_draft.id then 28.146 + ui.sectionRow("draft_updated_info", function() 28.147 + ui.container{ 28.148 + attr = { class = "info" }, 28.149 + content = _"The draft of this initiative has been updated!" 28.150 + } 28.151 + slot.put(" ") 28.152 + ui.link{ 28.153 + text = _"refresh my support", 28.154 + module = "initiative", 28.155 + action = "add_support", 28.156 + id = new_draft.initiative.id, 28.157 + params = { draft_id = new_draft.id }, 28.158 + routing = { 28.159 + default = { 28.160 + mode = "redirect", 28.161 + module = "initiative", 28.162 + view = "show", 28.163 + id = new_draft.initiative.id 28.164 + } 28.165 + } 28.166 + } 28.167 + 28.168 + slot.put(" · ") 28.169 + 28.170 + ui.link{ 28.171 + text = _"remove my support", 28.172 + module = "initiative", 28.173 + action = "remove_support", 28.174 + id = new_draft.initiative.id, 28.175 + routing = { 28.176 + default = { 28.177 + mode = "redirect", 28.178 + module = "initiative", 28.179 + view = "show", 28.180 + id = new_draft.initiative.id 28.181 + } 28.182 + } 28.183 + } 28.184 + 28.185 + end ) 28.186 end 28.187 - } 28.188 -end 28.189 + end 28.190 + 28.191 + ui.sectionRow( function() 28.192 28.193 + if not status then 28.194 + ui.field.text{ value = _"The drafts do not differ" } 28.195 + else 28.196 + ui.container{ 28.197 + tag = "div", 28.198 + attr = { class = "diff" }, 28.199 + content = function() 28.200 + output = output:gsub("[^\n\r]+", function(line) 28.201 + process_line(line) 28.202 + end) 28.203 + end 28.204 + } 28.205 + end 28.206 + 28.207 + end ) 28.208 +end ) 28.209 \ No newline at end of file
29.1 --- a/app/main/draft/list.lua Thu Jul 10 01:02:43 2014 +0200 29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 29.3 @@ -1,61 +0,0 @@ 29.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.number)) 29.5 - 29.6 -execute.view{ 29.7 - module = "initiative", view = "_show", params = { 29.8 - initiative = initiative, show_as_head = true 29.9 - } 29.10 -} 29.11 - 29.12 -ui.link{ 29.13 - text = _"Back to initiative", 29.14 - module = "initiative", view = "show", id = initiative.id 29.15 -} 29.16 - 29.17 -slot.put("<br />") 29.18 -slot.put("<br />") 29.19 - 29.20 -ui.form{ 29.21 - method = "get", 29.22 - module = "draft", 29.23 - view = "diff", 29.24 - content = function() 29.25 - ui.list{ 29.26 - records = initiative.drafts, 29.27 - columns = { 29.28 - { 29.29 - label = _"Created at", 29.30 - content = function(record) 29.31 - ui.field.text{ readonly = true, value = format.timestamp(record.created) } 29.32 - end 29.33 - }, 29.34 - { 29.35 - label = _"Author", 29.36 - content = function(record) 29.37 - if record.author then 29.38 - return record.author:ui_field_text() 29.39 - end 29.40 - end 29.41 - }, 29.42 - { 29.43 - content = function(record) 29.44 - ui.link{ 29.45 - attr = { class = "action" }, 29.46 - text = _"Show", 29.47 - module = "draft", 29.48 - view = "show", 29.49 - id = record.id 29.50 - } 29.51 - end 29.52 - }, 29.53 - { 29.54 - label = _"Compare", 29.55 - content = function(record) 29.56 - slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(record.id) .. '">') 29.57 - slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(record.id) .. '">') 29.58 - end 29.59 - } 29.60 - } 29.61 - } 29.62 - ui.submit{ text = _"Compare" } 29.63 - end 29.64 -}
30.1 --- a/app/main/draft/new.lua Thu Jul 10 01:02:43 2014 +0200 30.2 +++ b/app/main/draft/new.lua Thu Jul 10 01:19:48 2014 +0200 30.3 @@ -1,24 +1,27 @@ 30.4 -slot.put_into("title", _"Edit draft") 30.5 +local initiative = Initiative:by_id(param.get("initiative_id")) 30.6 +initiative:load_everything_for_member_id(app.session.member_id) 30.7 +initiative.issue:load_everything_for_member_id(app.session.member_id) 30.8 30.9 -local initiative = Initiative:by_id(param.get("initiative_id")) 30.10 30.11 -ui.actions(function() 30.12 - ui.link{ 30.13 - content = function() 30.14 - ui.image{ static = "icons/16/cancel.png" } 30.15 - slot.put(_"Cancel") 30.16 - end, 30.17 - module = "initiative", 30.18 - view = "show", 30.19 - id = initiative.id 30.20 +execute.view{ 30.21 + module = "issue", view = "_head", params = { 30.22 + issue = initiative.issue, 30.23 + initiative = initiative 30.24 } 30.25 -end) 30.26 +} 30.27 + 30.28 +execute.view { 30.29 + module = "issue", view = "_sidebar_issue", 30.30 + params = { 30.31 + issue = initiative.issue, 30.32 + } 30.33 +} 30.34 30.35 30.36 30.37 ui.form{ 30.38 record = initiative.current_draft, 30.39 - attr = { class = "vertical" }, 30.40 + attr = { class = "vertical section" }, 30.41 module = "draft", 30.42 action = "add", 30.43 params = { initiative_id = initiative.id }, 30.44 @@ -31,78 +34,103 @@ 30.45 } 30.46 }, 30.47 content = function() 30.48 - 30.49 - ui.field.text{ label = _"Unit", value = initiative.issue.area.unit.name, readonly = true } 30.50 - ui.field.text{ label = _"Area", value = initiative.issue.area.name, readonly = true } 30.51 - ui.field.text{ label = _"Policy", value = initiative.issue.policy.name, readonly = true } 30.52 - ui.field.text{ label = _"Issue", value = _("Issue ##{id}", { id = initiative.issue.id } ), readonly = true } 30.53 - slot.put("<br />") 30.54 - ui.field.text{ label = _"Initiative", value = initiative.name, readonly = true } 30.55 - 30.56 + 30.57 + ui.sectionHead( function() 30.58 + ui.heading { level = 1, content = initiative.display_name } 30.59 + end) 30.60 + 30.61 if param.get("preview") then 30.62 - ui.container{ 30.63 - attr = { class = "draft_content wiki" }, 30.64 - content = function() 30.65 - slot.put(format.wiki_text(param.get("content"), param.get("formatting_engine"))) 30.66 + ui.sectionRow( function() 30.67 + ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") } 30.68 + ui.field.hidden{ name = "content", value = param.get("content") } 30.69 + if config.enforce_formatting_engine then 30.70 + formatting_engine = config.enforce_formatting_engine 30.71 + else 30.72 + formatting_engine = param.get("formatting_engine") 30.73 end 30.74 - } 30.75 - slot.put("<br />") 30.76 - ui.submit{ text = _"Save" } 30.77 - slot.put("<br />") 30.78 - slot.put("<br />") 30.79 - end 30.80 - slot.put("<br />") 30.81 + ui.container{ 30.82 + attr = { class = "draft" }, 30.83 + content = function() 30.84 + slot.put(format.wiki_text(param.get("content"), formatting_engine)) 30.85 + end 30.86 + } 30.87 30.88 + slot.put("<br />") 30.89 + ui.tag{ 30.90 + tag = "input", 30.91 + attr = { 30.92 + type = "submit", 30.93 + class = "btn btn-default", 30.94 + value = _'Publish now' 30.95 + }, 30.96 + content = "" 30.97 + } 30.98 + slot.put("<br />") 30.99 + slot.put("<br />") 30.100 30.101 - ui.field.select{ 30.102 - label = _"Wiki engine", 30.103 - name = "formatting_engine", 30.104 - foreign_records = { 30.105 - { id = "rocketwiki", name = "RocketWiki" }, 30.106 - { id = "compat", name = _"Traditional wiki syntax" } 30.107 - }, 30.108 - attr = {id = "formatting_engine"}, 30.109 - foreign_id = "id", 30.110 - foreign_name = "name" 30.111 - } 30.112 - ui.tag{ 30.113 - tag = "div", 30.114 - content = function() 30.115 ui.tag{ 30.116 - tag = "label", 30.117 - attr = { class = "ui_field_label" }, 30.118 - content = function() slot.put(" ") end, 30.119 + tag = "input", 30.120 + attr = { 30.121 + type = "submit", 30.122 + name = "edit", 30.123 + class = "btn-link", 30.124 + value = _'Edit again' 30.125 + }, 30.126 + content = "" 30.127 + } 30.128 + slot.put(" | ") 30.129 + ui.link{ 30.130 + content = _"Cancel", 30.131 + module = "initiative", 30.132 + view = "show", 30.133 + id = initiative.id 30.134 + } 30.135 + end ) 30.136 + 30.137 + else 30.138 + ui.sectionRow( function() 30.139 + execute.view{ module = "initiative", view = "_sidebar_wikisyntax" } 30.140 + 30.141 + if not config.enforce_formatting_engine then 30.142 + ui.field.select{ 30.143 + label = _"Wiki engine", 30.144 + name = "formatting_engine", 30.145 + foreign_records = config.formatting_engines, 30.146 + attr = {id = "formatting_engine"}, 30.147 + foreign_id = "id", 30.148 + foreign_name = "name" 30.149 + } 30.150 + end 30.151 + 30.152 + ui.heading{ level = 2, content = _"Enter your proposal and/or reasons" } 30.153 + 30.154 + ui.field.text{ 30.155 + name = "content", 30.156 + multiline = true, 30.157 + attr = { style = "height: 50ex; width: 100%;" }, 30.158 + value = param.get("content") 30.159 } 30.160 ui.tag{ 30.161 - content = function() 30.162 - ui.link{ 30.163 - text = _"Syntax help", 30.164 - module = "help", 30.165 - view = "show", 30.166 - id = "wikisyntax", 30.167 - attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 30.168 - } 30.169 - slot.put(" ") 30.170 - ui.link{ 30.171 - text = _"(new window)", 30.172 - module = "help", 30.173 - view = "show", 30.174 - id = "wikisyntax", 30.175 - attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 30.176 - } 30.177 - end 30.178 + tag = "input", 30.179 + attr = { 30.180 + type = "submit", 30.181 + name = "preview", 30.182 + class = "btn btn-default", 30.183 + value = _'Preview' 30.184 + }, 30.185 + content = "" 30.186 } 30.187 - end 30.188 - } 30.189 - ui.field.text{ 30.190 - label = _"Content", 30.191 - name = "content", 30.192 - multiline = true, 30.193 - attr = { style = "height: 50ex;" }, 30.194 - value = param.get("content") 30.195 - } 30.196 - 30.197 - ui.submit{ name = "preview", text = _"Preview" } 30.198 - ui.submit{ text = _"Save" } 30.199 + slot.put("<br />") 30.200 + slot.put("<br />") 30.201 + 30.202 + ui.link{ 30.203 + content = _"Cancel", 30.204 + module = "initiative", 30.205 + view = "show", 30.206 + id = initiative.id 30.207 + } 30.208 + 30.209 + end ) 30.210 + end 30.211 end 30.212 }
31.1 --- a/app/main/draft/show.lua Thu Jul 10 01:02:43 2014 +0200 31.2 +++ b/app/main/draft/show.lua Thu Jul 10 01:19:48 2014 +0200 31.3 @@ -2,39 +2,51 @@ 31.4 local source = param.get("source", atom.boolean) 31.5 31.6 execute.view{ 31.7 - module = "draft", 31.8 + module = "issue", 31.9 view = "_head", 31.10 - params = { draft = draft} 31.11 + params = { issue = draft.initiative.issue } 31.12 } 31.13 31.14 -slot.put_into("title", " · " .. _"History") 31.15 - 31.16 -if source then 31.17 - ui.actions(function() 31.18 - ui.link{ 31.19 - content = _"Rendered", 31.20 - module = "draft", 31.21 - view = "show", 31.22 - id = param.get_id(), 31.23 - params = { source = false } 31.24 - } 31.25 - end 31.26 - ) 31.27 -else 31.28 - ui.actions(function() 31.29 +ui.section( function() 31.30 + 31.31 + ui.sectionHead( function() 31.32 ui.link{ 31.33 - content = _"Source", 31.34 - module = "draft", 31.35 - view = "show", 31.36 - id = param.get_id(), 31.37 - params = { source = true } 31.38 + module = "initiative", view = "show", id = draft.initiative.id, 31.39 + content = function () 31.40 + ui.heading { 31.41 + level = 1, 31.42 + content = draft.initiative.display_name 31.43 + } 31.44 + end 31.45 } 31.46 - end 31.47 - ) 31.48 -end 31.49 - 31.50 -execute.view{ 31.51 - module = "draft", 31.52 - view = "_show", 31.53 - params = { draft = draft, source = source } 31.54 -} 31.55 + ui.container { attr = { class = "right" }, content = function() 31.56 + if source then 31.57 + ui.link{ 31.58 + content = _"Rendered", 31.59 + module = "draft", 31.60 + view = "show", 31.61 + id = param.get_id(), 31.62 + params = { source = false } 31.63 + } 31.64 + else 31.65 + ui.link{ 31.66 + content = _"Source", 31.67 + module = "draft", 31.68 + view = "show", 31.69 + id = param.get_id(), 31.70 + params = { source = true } 31.71 + } 31.72 + end 31.73 + end } 31.74 + ui.heading { level = 2, content = _("Draft revision #{id}", { id = draft.id } ) } 31.75 + end) 31.76 + 31.77 + ui.sectionRow( function() 31.78 + 31.79 + execute.view{ 31.80 + module = "draft", 31.81 + view = "_show", 31.82 + params = { draft = draft, source = source } 31.83 + } 31.84 + end) 31.85 +end)
32.1 --- a/app/main/event/_list.lua Thu Jul 10 01:02:43 2014 +0200 32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 32.3 @@ -1,227 +0,0 @@ 32.4 ---local global = param.get("global", atom.boolean) 32.5 -local for_member = param.get("for_member", "table") 32.6 -local for_unit = param.get("for_unit", "table") 32.7 -local for_area = param.get("for_area", "table") 32.8 -local event_max_id = param.get_all_cgi()["event_max_id"] 32.9 -local event_selector = Event:new_selector() 32.10 - :add_order_by("event.id DESC") 32.11 - :limit(25) 32.12 - :join("issue", nil, "issue.id = event.issue_id") 32.13 - :add_field("now()::date - event.occurrence::date", "time_ago") 32.14 - 32.15 -if event_max_id then 32.16 - event_selector:add_where{ "event.id < ?", event_max_id } 32.17 -end 32.18 - 32.19 -if for_member then 32.20 - event_selector:add_where{ "event.member_id = ?", for_member.id } 32.21 -elseif for_unit then 32.22 - event_selector:join("area", nil, "area.id = issue.area_id") 32.23 - event_selector:add_where{ "area.unit_id = ?", for_unit.id } 32.24 -elseif for_area then 32.25 - event_selector:add_where{ "issue.area_id = ?", for_area.id } 32.26 ---elseif not global then 32.27 --- event_selector:join("event_seen_by_member", nil, { "event_seen_by_member.id = event.id AND event_seen_by_member.seen_by_member_id = ?", app.session.member_id }) 32.28 -end 32.29 - 32.30 -if app.session.member_id then 32.31 - event_selector 32.32 - :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id } ) 32.33 - :add_field("(_interest.member_id NOTNULL)", "is_interested") 32.34 - :left_join("delegating_interest_snapshot", "_delegating_interest", { "_delegating_interest.issue_id = issue.id AND _delegating_interest.member_id = ? AND _delegating_interest.event = issue.latest_snapshot_event", app.session.member.id } ) 32.35 - :add_field("_delegating_interest.delegate_member_ids[1]", "is_interested_by_delegation_to_member_id") 32.36 - :add_field("_delegating_interest.delegate_member_ids[array_upper(_delegating_interest.delegate_member_ids, 1)]", "is_interested_via_member_id") 32.37 - :add_field("array_length(_delegating_interest.delegate_member_ids, 1)", "delegation_chain_length") 32.38 -end 32.39 - 32.40 -local filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = { 32.41 - for_events = true, 32.42 - member = app.session.member, for_member = for_member, state = for_state, for_unit = for_unit and true or false, for_area = for_area and true or false 32.43 -}} 32.44 - 32.45 -filters.opened = true 32.46 -filters.selector = event_selector 32.47 - 32.48 -filters.content = function() 32.49 - 32.50 - 32.51 - local last_event_id 32.52 - 32.53 - local events = event_selector:exec() 32.54 - 32.55 - local issues = events:load("issue") 32.56 - issues:load_everything_for_member_id(app.session.member_id) 32.57 - 32.58 - events:load("initiative") 32.59 - events:load("suggestion") 32.60 - events:load("member") 32.61 - 32.62 - 32.63 - ui.container{ attr = { class = "issues events" }, content = function() 32.64 - 32.65 - local last_event_date 32.66 - for i, event in ipairs(events) do 32.67 - last_event_id = event.id 32.68 - 32.69 - ui.container{ attr = { class = "event_info" }, content = function() 32.70 - local event_name = event.event_name 32.71 - local event_image 32.72 - if event.event == "issue_state_changed" then 32.73 - if event.state == "discussion" then 32.74 - event_name = _"Discussion started" 32.75 - event_image = "comments.png" 32.76 - elseif event.state == "verification" then 32.77 - event_name = _"Verification started" 32.78 - event_image = "lock.png" 32.79 - elseif event.state == "voting" then 32.80 - event_name = _"Voting started" 32.81 - event_image = "email_open.png" 32.82 - elseif event.state == "finished_with_winner" then 32.83 - event_name = event.state_name 32.84 - event_image = "award_star_gold_2.png" 32.85 - elseif event.state == "finished_without_winner" then 32.86 - event_name = event.state_name 32.87 - event_image = "cross.png" 32.88 - else 32.89 - event_name = event.state_name 32.90 - end 32.91 - if event_image then 32.92 - ui.image{ static = "icons/16/" .. event_image } 32.93 - slot.put(" ") 32.94 - end 32.95 - end 32.96 - local days_ago_text 32.97 - if event.time_ago == 0 then 32.98 - days_ago_text = _("Today at #{time}", { time = format.time(event.occurrence) }) 32.99 - elseif event.time_ago == 1 then 32.100 - days_ago_text = _("Yesterday at #{time}", { time = format.time(event.occurrence) }) 32.101 - else 32.102 - days_ago_text = _("#{date} at #{time}", { date = format.date(event.occurrence.date), time = format.time(event.occurrence, { hide_seconds = true }) }) 32.103 - end 32.104 - ui.tag{ attr = { class = "event_name" }, content = event_name } 32.105 - slot.put("<br />") 32.106 - ui.tag{ content = days_ago_text } 32.107 - --[[ if event.time_ago > 1 then 32.108 - slot.put("<br />(") 32.109 - ui.tag{ content = _("#{count} days ago", { count = event.time_ago }) } 32.110 - slot.put(")") 32.111 - end 32.112 - --]] 32.113 - if app.session:has_access("authors_pseudonymous") and event.member_id then 32.114 - slot.put("<br />") 32.115 - slot.put("<br />") 32.116 - if app.session.member_id then 32.117 - ui.link{ 32.118 - content = function() 32.119 - execute.view{ 32.120 - module = "member_image", 32.121 - view = "_show", 32.122 - params = { 32.123 - member = event.member, 32.124 - image_type = "avatar", 32.125 - show_dummy = true, 32.126 - class = "micro_avatar", 32.127 - popup_text = text 32.128 - } 32.129 - } 32.130 - end, 32.131 - module = "member", view = "show", id = event.member_id 32.132 - } 32.133 - slot.put(" ") 32.134 - end 32.135 - ui.link{ 32.136 - text = event.member.name, 32.137 - module = "member", view = "show", id = event.member_id 32.138 - } 32.139 - end 32.140 - end } 32.141 - 32.142 - ui.container{ attr = { class = "issue" }, content = function() 32.143 - 32.144 - execute.view{ module = "delegation", view = "_info", params = { issue = event.issue, member = for_member } } 32.145 - 32.146 - ui.container{ attr = { class = "content" }, content = function() 32.147 - ui.link{ 32.148 - module = "unit", view = "show", id = event.issue.area.unit_id, 32.149 - attr = { class = "unit_link" }, text = event.issue.area.unit.name 32.150 - } 32.151 - slot.put(" ") 32.152 - ui.link{ 32.153 - module = "area", view = "show", id = event.issue.area_id, 32.154 - attr = { class = "area_link" }, text = event.issue.area.name 32.155 - } 32.156 - end } 32.157 - 32.158 - ui.container{ attr = { class = "title" }, content = function() 32.159 - ui.link{ 32.160 - attr = { class = "issue_id" }, 32.161 - text = _("#{policy} ##{id}", { policy = event.issue.policy.name, id = event.issue_id }), 32.162 - module = "issue", 32.163 - view = "show", 32.164 - id = event.issue_id 32.165 - } 32.166 - end } 32.167 - 32.168 - ui.container{ attr = { class = "initiative_list" }, content = function() 32.169 - if not event.initiative_id then 32.170 - local initiatives_selector = Initiative:new_selector() 32.171 - :add_where{ "initiative.issue_id = ?", event.issue_id } 32.172 - :add_order_by("initiative.admitted DESC NULLS LAST, initiative.rank NULLS LAST, initiative.harmonic_weight DESC NULLS LAST, id") 32.173 - execute.view{ module = "initiative", view = "_list", params = { 32.174 - issue = event.issue, 32.175 - initiatives_selector = initiatives_selector, 32.176 - no_sort = true, 32.177 - limit = 5, 32.178 - for_member = for_member 32.179 - } } 32.180 - else 32.181 - local initiatives_selector = Initiative:new_selector() 32.182 - :add_where{ "initiative.id = ?", event.initiative_id } 32.183 - execute.view{ module = "initiative", view = "_list", params = { 32.184 - initiatives_selector = initiatives_selector, 32.185 - no_sort = true, 32.186 - hide_more_initiatives = true, 32.187 - for_member = for_member 32.188 - } } 32.189 - end 32.190 - end } 32.191 - 32.192 - ui.container{ attr = { class = "content suggestion" }, content = function() 32.193 - if event.suggestion_id then 32.194 - ui.link{ 32.195 - text = event.suggestion.name, 32.196 - module = "suggestion", view = "show", id = event.suggestion_id 32.197 - } 32.198 - end 32.199 - end } 32.200 - end } 32.201 - end 32.202 - 32.203 - end } 32.204 - 32.205 - slot.put("<br />") 32.206 - 32.207 - if #events > 0 then 32.208 - ui.link{ 32.209 - attr = { class = "more_events_links" }, 32.210 - text = _"Show older events", 32.211 - module = request.get_module(), 32.212 - view = request.get_view(), 32.213 - id = for_unit and for_unit.id or for_area and for_area.id, 32.214 - params = { 32.215 - tab = param.get_all_cgi()["tab"], 32.216 - events = param.get_all_cgi()["events"], 32.217 - event_max_id = last_event_id 32.218 - } 32.219 - } 32.220 - else 32.221 - ui.tag{ content = _"No more events available" } 32.222 - end 32.223 - 32.224 - slot.put("<br />") 32.225 - slot.put("<br />") 32.226 - 32.227 -end 32.228 - 32.229 - 32.230 -ui.filters(filters)
33.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 33.2 +++ b/app/main/help/introduction.lua Thu Jul 10 01:19:48 2014 +0200 33.3 @@ -0,0 +1,132 @@ 33.4 +ui.title(_"Introduction") 33.5 + 33.6 +local lang = locale.get("lang") 33.7 + 33.8 +ui.section(function() 33.9 + ui.sectionHead(function() 33.10 + ui.heading{ level = 1, content = _"Structured discussion" } 33.11 + end) 33.12 + ui.sectionRow(function() 33.13 + ui.heading{ level = 2, content = _"Initiatives and issues" } 33.14 + if lang == "de" then 33.15 + ui.tag{ tag = "p", content = [[ 33.16 + LiquidFeedback ist kein Umfragesystem, es werden keine bereits vorher feststehenden Fragen gestellt. Statt dessen kann jeder Teilnehmer neue Initiativen starten, die Vorschläge und/oder Argumente umfassen. Sobald eine Initiative eingestellt wurde, können alle Teilnehmer alternative Initiativen mit Gegenvorschlägen starten. Alle zueinander in Konkrurrenz stehenden Initiativen bilden zusammen ein Thema. Sowohl Themen als auch Initiativen werden nummeriert. Themen erhalten hierbei vor der Nummer ein #-Zeichen (z. B. #123), während Initiativen durch ein führendes i gekennzeichnet sind (z. B. i456). Ein Thema kann mehrere Initiativen enthalten. Nur eine Initiative kann gewinnen. 33.17 + ]] } 33.18 + else 33.19 + ui.tag{ tag = "p", content = [[ 33.20 + LiquidFeedback is no survey, it doesn't ask you predefined questions. Instead every participant is allowed to post new initiatives containing a proposal and/or reasoning. As soon as the initiative is posted, all other participants can create alternative initiatives with counter proposals and/or reasoning. A group of concurring initiatives forms an issue. Issues in LiquidFeedback are numbered with a hash sign (e.g. #123) while initiatives are numbered with a leading "i" character (i456). In short: One issue may contain multiple initiatives. Only one initiative can win. 33.21 + ]] } 33.22 + end 33.23 + 33.24 + ui.heading{ level = 2, content = _"Subject areas" } 33.25 + if lang == "de" then 33.26 + ui.tag{ tag = "p", content = [[ 33.27 + Themen werden immer einem Themenbereich zugeordnet. Dies dient der Strukturierung der Diskussion und des Entscheidungsprozesses. 33.28 + ]] } 33.29 + else 33.30 + ui.tag{ tag = "p", content = [[ 33.31 + Issues are always assigned to a subject area in order to structure the discussion and decision process. 33.32 + ]] } 33.33 + end 33.34 + ui.heading{ level = 2, content = _"Organizational units" } 33.35 + if lang == "de" then 33.36 + ui.tag{ tag = "p", content = [[ 33.37 + Gliederungen ermöglichen Diskussionen und Entscheidungen auch für Teilmengen der Benutzer (z. B. Gliederungen einer Organisation). In jeder Gliederung können eigene Themenbereiche zur Verfügung stehen. 33.38 + ]] } 33.39 + else 33.40 + ui.tag{ tag = "p", content = [[ 33.41 + To allow discussions and decisions by sub groups of participants (e.g. by the members of a subdivision of an organization), participants can be assigned to different units. Every organizational unit can have its own subject areas. 33.42 + ]] } 33.43 + end 33.44 + ui.heading{ level = 2, content = _"Rules of procedure" } 33.45 + if lang == "de" then 33.46 + ui.tag{ tag = "p", content = [[ 33.47 + Ein Regelwerk definiert Fristen, Quoren und erforderliche Mehrheiten. Initiatoren wählen bei Erstellung eines Themas ein geeignetes Verfahren, das dem verfolgten Zweck entspricht. 33.48 + ]] } 33.49 + else 33.50 + ui.tag{ tag = "p", content = [[ 33.51 + A policy defines the timing, quorums and required majorities for an issue in LiquidFeedback. Initiators choose the fitting policy for their purpose when creating a new issue. 33.52 + ]] } 33.53 + end 33.54 + end ) 33.55 +end ) 33.56 +ui.section(function() 33.57 + ui.sectionHead(function() 33.58 + ui.heading{ level = 1, content = _"4 phases of a decision" } 33.59 + end) 33.60 + ui.sectionRow(function() 33.61 + ui.heading{ level = 2, content = _"(1) Admission phase" } 33.62 + if lang == "de" then 33.63 + ui.tag{ tag = "p", content = [[ 33.64 + Nicht jedes neue Thema wird auf ein Mindestinteresse der Teilnehmer stoßen. Daher muss ein neues Thema von einer vorab festzulegenden Mindestanzahl Teilnehmer als diskussionswürdig betrachtet werden, um für die Diskussionsphase zugelassen zu werden. Andernfalls wird das Thema am Ende der Zulassungsphase abgebrochen und nicht weiter behandelt. 33.65 + ]] } 33.66 + else 33.67 + ui.tag{ tag = "p", content = [[ 33.68 + As every participant can open a new issue in LiquidFeedback, not all of them will be intersting for at least a minimum of the participants. Therefore new issues need to gain a given quorum of supporters to become accepted for further discussion. Issues which do not reach the necessary quorum will be closed at the end of the admission phase. 33.69 + ]] } 33.70 + end 33.71 + ui.heading{ level = 2, content = _"(2) Discussion phase" } 33.72 + if lang == "de" then 33.73 + ui.tag{ tag = "p", content = [[ 33.74 + Während der Diskussionsphase arbeiten Initiativen auf die Verbesserung des Vorschlags und die Vervollkommnung der Argumentation hin, um die erforderliche Mehrheit zu erreichen und sich gegen eventuell vorhandene alternative Initiativen durchzusetzen. 33.75 + ]] } 33.76 + else 33.77 + ui.tag{ tag = "p", content = [[ 33.78 + During the discussion phase all initiatives try to improve their proposals and reasoning to gain more supporters. The aim is to eventually reach the necessary majority and to beat alternative initiatives. 33.79 + ]] } 33.80 + end 33.81 + ui.heading{ level = 2, content = _"(3) Verification phase" } 33.82 + if lang == "de" then 33.83 + ui.tag{ tag = "p", content = [[ 33.84 + Alle in dieser Phase angezeigten Initiativtexte können nicht mehr verändert werden. Neue Initiativen können gestartet aber ebenfalls nicht mehr geändert werden. Dieses Vorgehen schützt die Teilnehmer vor überraschenden Änderungen in letzter Minute. 33.85 + ]] } 33.86 + else 33.87 + ui.tag{ tag = "p", content = [[ 33.88 + During the verification phase, initiative drafts with the proposal and reasoning become final and cannot be changed any more. So everyone can double check everything. In case of some last minute situation, it is still possible to add competing initiatives. But they cannot be edited again and need to gain supporters from scratch. 33.89 + ]] } 33.90 + end 33.91 + ui.heading{ level = 2, content = _"(4) Voting phase" } 33.92 + if lang == "de" then 33.93 + ui.tag{ tag = "p", content = [[ 33.94 + Jede Initiative, die eine Mindestanzahl an Unterstützern erreicht, wird zur Abstimmung zugelassen und erscheint auf dem Stimmzettel. Während der Abstimmung können die Teilnehmer mittels Präferenzwahl abstimmen, die es neben Zustimmung, Enthaltung und Ablehnung zusätzlich erlaubt Präferenzen zwischen den Initiativen anzugeben. 33.95 + ]] } 33.96 + else 33.97 + ui.tag{ tag = "p", content = [[ 33.98 + Every initiative reaching a required quorum of supporters at the end of the verification phase is admitted for voting and appears on the voting ballot. During the voting phase every eligible participant may give a vote using a preferential voting system allowing to express individual preferences between the initiatives in addition to a yes/neutral/no vote. 33.99 + ]] } 33.100 + end 33.101 + 33.102 + end) 33.103 +end) 33.104 +ui.section(function() 33.105 + ui.sectionHead(function() 33.106 + ui.heading{ level = 1, content = _"Vote delegation" } 33.107 + end) 33.108 + ui.sectionRow(function() 33.109 + if lang == "de" then 33.110 + ui.tag{ tag = "p", content = [[ 33.111 + Delegationen ermöglichen eine dynamische Arbeitsteilung. Sie entsprechen einer Stimmrechtsvollmacht, können jederzeit geändert werden, sind weisungsfrei und übertragbar. Delegationen können für eine Gliederung, für einen Themenbereich der Gliederung oder für ein konkretes Thema erteilt werden. Konkretere Delegationen gehen allgemeineren Delegationen vor. Delegationen werden sowohl für den Diskurs (Phasen 1 bis 3) als auch für die Abstimmphase genutzt. Bei Aktivität eines Benutzers werden eventuell vorhandene Delegationen für die jeweilige Aktivität ausgesetzt. 33.112 + ]] } 33.113 + else 33.114 + ui.tag{ tag = "p", content = [[ 33.115 + Delegations allow for a dynamic division of labor. A delegation is a proxy statement (voting power under a power of attorney), can be altered at any time, is not bound to directives and can be delegated onward. Delegations can be used for a whole organizational unit, for a subject area within an organizational unit, or for a specific issue. More specific delegations overrule more general delegations. Delegations are used in both the discourse (phase 1 to 3) and the voting phase. Any activity suspends existing delegations for the given activity. 33.116 + ]] } 33.117 + end 33.118 + end) 33.119 +end) 33.120 +ui.section(function() 33.121 + ui.sectionHead(function() 33.122 + ui.heading{ level = 1, content = _"Preference voting" } 33.123 + end) 33.124 + ui.sectionRow(function() 33.125 + if lang == "de" then 33.126 + ui.tag{ tag = "p", content = [[ 33.127 + Im Falle mehrerer ähnlicher Vorschläge auf dem Stimmzettel gibt es keine Notwendigkeit einen dieser Vorschläge auszuwählen. Stattdessen kann für (bzw. gegen) beliebig viele konkurrierende Initiativen gestimmt werden und gleichzeitig eine Präferenzreihenfolge dieser Initiativen angegeben werden. Die Präferenzen bestimmen den Gewinner, falls am Ende mehr als eine Initiative die notwendige Mehrheit an Ja-Stimmen erreicht. Auf diese Weise wird niemand ermutigt für eine Initiative zu stimmen, nur um eine andere Initiative zu verhindern, und es wird niemand ermutigt gegen eine Initiative zu stimmen, nur um einer anderen Initiative eine Chance zu geben. 33.128 + ]] } 33.129 + else 33.130 + ui.tag{ tag = "p", content = [[ 33.131 + If there are similar competing proposals on the ballot, there is no necessity to choose one of them. Instead, it is possible to vote for (and against) as many initiatives as one wants to while being able to express the individual preferences amongst those initiatives during voting phase. Those preferences will determine the winner if more than one initiative has reached the necessary majority of approvals at end of voting phase. That way, nobody is encouraged to vote in favor of one initiative just to outrank another one, and nobody is encouraged to vote against an initiative just to increase the chances for another initiative to win. 33.132 + ]] } 33.133 + end 33.134 + end) 33.135 +end)
34.1 --- a/app/main/index/404.lua Thu Jul 10 01:02:43 2014 +0200 34.2 +++ b/app/main/index/404.lua Thu Jul 10 01:19:48 2014 +0200 34.3 @@ -1,3 +1,13 @@ 34.4 ui.title("404 Not found") 34.5 34.6 -ui.container{ content = "Page not found" } 34.7 +ui.section(function() 34.8 + ui.sectionHead(function() 34.9 + ui.heading{ level = 1, content = _"Page not found" } 34.10 + end) 34.11 + ui.sectionRow(function() 34.12 + ui.link{ 34.13 + content = _"Go back to home page", 34.14 + module = "index", view = "index" 34.15 + } 34.16 + end) 34.17 +end) 34.18 \ No newline at end of file
35.1 --- a/app/main/index/_action/login.lua Thu Jul 10 01:02:43 2014 +0200 35.2 +++ b/app/main/index/_action/login.lua Thu Jul 10 01:19:48 2014 +0200 35.3 @@ -90,6 +90,18 @@ 35.4 if config.etherpad then 35.5 do_etherpad_auth(member) 35.6 end 35.7 + slot.select("script", function() 35.8 + ui.script{ script = [[ 35.9 + $('#swiper_info').addClass('active'); 35.10 + ]] } 35.11 + end) 35.12 + slot.select("swiper_info", function() 35.13 + ui.tag { content = _"select tabs" } 35.14 + slot.put(" ↑ ") 35.15 + ui.tag { content = _"or swipe" } 35.16 + slot.put(" ←<br />") 35.17 + ui.tag { content = _"to show more info and learn what you can do" } 35.18 + end ) 35.19 else 35.20 slot.select("error", function() 35.21 ui.tag{ content = _'Invalid login name or password!' }
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/app/main/index/_login.lua Thu Jul 10 01:19:48 2014 +0200 36.3 @@ -0,0 +1,37 @@ 36.4 +ui.form{ 36.5 + attr = { class = "login" }, 36.6 + module = 'index', 36.7 + action = 'login', 36.8 + routing = { 36.9 + ok = { 36.10 + mode = 'redirect', 36.11 + module = param.get("redirect_module") or "index", 36.12 + view = param.get("redirect_view") or "index", 36.13 + id = param.get("redirect_id"), 36.14 + }, 36.15 + error = { 36.16 + mode = 'forward', 36.17 + module = 'index', 36.18 + view = 'login', 36.19 + } 36.20 + }, 36.21 + content = function() 36.22 + ui.field.text{ 36.23 + attr = { id = "username_field" }, 36.24 + label = _'login name', 36.25 + html_name = 'login', 36.26 + value = '' 36.27 + } 36.28 + ui.script{ script = 'document.getElementById("username_field").focus();' } 36.29 + ui.field.password{ 36.30 + label = _'Password', 36.31 + html_name = 'password', 36.32 + value = '' 36.33 + } 36.34 + ui.submit{ 36.35 + text = _'Login' 36.36 + } 36.37 + slot.put(" ") 36.38 + ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" } 36.39 + end 36.40 +} 36.41 \ No newline at end of file
37.1 --- a/app/main/index/_motd.lua Thu Jul 10 01:02:43 2014 +0200 37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 37.3 @@ -1,9 +0,0 @@ 37.4 -if config.motd_intern then 37.5 - local help_text = config.motd_intern 37.6 - ui.container{ 37.7 - attr = { class = "wiki" }, 37.8 - content = function() 37.9 - slot.put(format.wiki_text(help_text)) 37.10 - end 37.11 - } 37.12 -end
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/app/main/index/_sidebar_members.lua Thu Jul 10 01:19:48 2014 +0200 38.3 @@ -0,0 +1,33 @@ 38.4 +if not app.session:has_access("all_pseudonymous") then 38.5 + return 38.6 +end 38.7 + 38.8 +ui.sidebar ( "tab-members", function () 38.9 + local member_count = MemberCount:get() 38.10 + ui.sidebarHead( function() 38.11 + ui.heading { 38.12 + level = 2, 38.13 + content = _("Registered members (#{count})", { count = member_count }) 38.14 + } 38.15 + end ) 38.16 + 38.17 + local selector = Member:new_selector() 38.18 + :add_where("active") 38.19 + :add_order_by("last_login DESC NULLS LAST, id DESC") 38.20 + :limit(50) 38.21 + 38.22 + execute.view { 38.23 + module = 'member', view = '_list', params = { 38.24 + members_selector = selector, 38.25 + no_filter = true, no_paginate = true, 38.26 + member_class = "sidebarRow sidebarRowNarrow" 38.27 + } 38.28 + } 38.29 + 38.30 + ui.link { 38.31 + attr = { class = "sidebarRow moreLink" }, 38.32 + text = _"Show full member list", 38.33 + module = "member", view = "list" 38.34 + } 38.35 + 38.36 +end )
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/app/main/index/_sidebar_motd_intern.lua Thu Jul 10 01:19:48 2014 +0200 39.3 @@ -0,0 +1,10 @@ 39.4 +if config.motd_intern then 39.5 + slot.select("motd", function() 39.6 + ui.container{ 39.7 + attr = { class = "wiki motd" }, 39.8 + content = function() 39.9 + slot.put(config.motd_intern) 39.10 + end 39.11 + } 39.12 + end ) 39.13 +end
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/app/main/index/_sidebar_motd_public.lua Thu Jul 10 01:19:48 2014 +0200 40.3 @@ -0,0 +1,10 @@ 40.4 +if config.motd_public then 40.5 + slot.select("motd", function() 40.6 + ui.container{ 40.7 + attr = { class = "wiki motd" }, 40.8 + content = function() 40.9 + slot.put(config.motd_public) 40.10 + end 40.11 + } 40.12 + end ) 40.13 +end
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/app/main/index/_sidebar_notifications.lua Thu Jul 10 01:19:48 2014 +0200 41.3 @@ -0,0 +1,132 @@ 41.4 +local notification_links = {} 41.5 + 41.6 +if app.session.member.notify_email_unconfirmed then 41.7 + notification_links[#notification_links+1] = { 41.8 + module = "index", view = "email_unconfirmed", 41.9 + text = _"Confirm your email address" 41.10 + } 41.11 +end 41.12 + 41.13 +if app.session.member.notify_level == nil then 41.14 + notification_links[#notification_links+1] = { 41.15 + module = "member", view = "settings_notification", 41.16 + text = _"Select a notification level" 41.17 + } 41.18 +end 41.19 + 41.20 +if config.check_delegations_interval_soft then 41.21 + local member = Member:new_selector() 41.22 + :add_where({ "id = ?", app.session.member_id }) 41.23 + :add_field({ "now() > COALESCE(last_delegation_check, activated) + ?::interval", config.check_delegations_interval_soft }, "needs_delegation_check_soft") 41.24 + :single_object_mode() 41.25 + :exec() 41.26 + 41.27 + 41.28 + if member.needs_delegation_check_soft then 41.29 + 41.30 + local delegations = Delegation:delegations_to_check_for_member_id(member.id) 41.31 + 41.32 + if #delegations > 0 then 41.33 + notification_links[#notification_links+1] = { 41.34 + module = "index", view = "check_delegations", 41.35 + text = _"Check your outgoing delegations" 41.36 + } 41.37 + end 41.38 + 41.39 + end 41.40 +end 41.41 + 41.42 +local broken_delegations = Delegation:selector_for_broken(app.session.member_id):exec() 41.43 + 41.44 +for i, delegation in ipairs(broken_delegations) do 41.45 + local scope 41.46 + local context 41.47 + if delegation.scope == "unit" then 41.48 + scope = _"unit" 41.49 + id = delegation.unit_id 41.50 + context = delegation.unit.name 41.51 + elseif delegation.scope == "area" then 41.52 + scope = _"area" 41.53 + id = delegation.area_id 41.54 + context = delegation.area.name 41.55 + elseif delegation.scope == "issue" then 41.56 + scope = _"issue" 41.57 + id = delegation.issue_id 41.58 + context = delegation.issue.name 41.59 + end 41.60 + 41.61 + notification_links[#notification_links+1] = { 41.62 + module = delegation.scope, view = "show", id = id, 41.63 + text = _("Check your #{scope} delegation to '#{trustee_name}' for '#{context}'", { 41.64 + trustee_name = delegation.trustee.name, 41.65 + scope = scope, 41.66 + context = context 41.67 + }) 41.68 + } 41.69 +end 41.70 + 41.71 +local selector = Issue:new_selector() 41.72 + :join("area", nil, "area.id = issue.area_id") 41.73 + :join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", app.session.member_id }) 41.74 + :left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", app.session.member.id }) 41.75 + :left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", app.session.member.id }) 41.76 + :left_join("interest", nil, { "interest.issue_id = issue.id AND interest.member_id = ?", app.session.member.id }) 41.77 + :add_where{ "direct_voter.member_id ISNULL" } 41.78 + :add_where{ "non_voter.member_id ISNULL" } 41.79 + :add_where{ "interest.member_id NOTNULL" } 41.80 + :add_where{ "issue.fully_frozen NOTNULL" } 41.81 + :add_where{ "issue.closed ISNULL" } 41.82 + :add_order_by{ "issue.fully_frozen + issue.voting_time ASC" } 41.83 + 41.84 +local issues_to_vote = selector:exec() 41.85 + 41.86 +for i, issue in ipairs(issues_to_vote) do 41.87 + notification_links[#notification_links+1] = { 41.88 + module = "issue", view = "show", id = issue.id, 41.89 + text = _("#{issue} is in voting", { issue = issue.name }) 41.90 + } 41.91 +end 41.92 + 41.93 +local initiator_invites = Initiator:selector_for_invites(app.session.member_id):exec() 41.94 + 41.95 +for i, initiative in ipairs(initiator_invites) do 41.96 + notification_links[#notification_links+1] = { 41.97 + module = "initiative", view = "show", id = initiative.id, 41.98 + text = _("You are invited to become initiator of '#{initiative_name}'", { initiative_name = initiative.display_name }) 41.99 + } 41.100 +end 41.101 + 41.102 +updated_drafts = Initiative:selector_for_updated_drafts(app.session.member_id):exec() 41.103 + 41.104 +for i, initiative in ipairs(updated_drafts) do 41.105 + notification_links[#notification_links+1] = { 41.106 + module = "initiative", view = "show", id = initiative.id, 41.107 + text = _("New draft for initiative '#{initiative_name}'", { initiative_name = initiative.display_name }) 41.108 + } 41.109 +end 41.110 + 41.111 +local mode = param.get("mode") or "view" 41.112 + 41.113 +if #notification_links > 0 then 41.114 + if mode == "link" then 41.115 + slot.select("notification", function () 41.116 + local text = _"notifications" 41.117 + ui.link { 41.118 + attr = { class = "notifications", title = text }, 41.119 + module = "index", view = "notifications", 41.120 + content = function () 41.121 + ui.image { attr = { class = "icon", alt = text }, static = "icons/48/bell.png" } 41.122 + ui.tag { attr = { class = "count" }, content = #notification_links } 41.123 + end 41.124 + } 41.125 + end ) 41.126 + elseif mode == "view" then 41.127 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 41.128 + for i, notification_link in ipairs(notification_links) do 41.129 + ui.tag{ tag = "li", content = function() 41.130 + ui.link(notification_link) 41.131 + end } 41.132 + end 41.133 + end } 41.134 + end 41.135 +end
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/app/main/index/_sidebar_units.lua Thu Jul 10 01:19:48 2014 +0200 42.3 @@ -0,0 +1,154 @@ 42.4 +local member = param.get ( "member", "table" ) 42.5 +local units 42.6 +if member then 42.7 + units = member.units 42.8 + units:load_delegation_info_once_for_member_id(member.id) 42.9 +else 42.10 + units = Unit:new_selector():add_where("active"):add_order_by("name"):exec() 42.11 + ui.sidebar( "tab-whatcanido", function() 42.12 + ui.sidebarHead( function() 42.13 + ui.heading { level = 2, content = _"Organizational units" } 42.14 + end ) 42.15 + ui.sidebarSection( function() 42.16 + execute.view { module = "unit", view = "_list" } 42.17 + end ) 42.18 + end ) 42.19 + return 42.20 +end 42.21 + 42.22 + 42.23 +for i, unit in ipairs(units) do 42.24 + 42.25 + ui.sidebar ( "tab-whatcanido units", function () 42.26 + 42.27 + local areas_selector = Area:new_selector() 42.28 + :reset_fields() 42.29 + :add_field("area.id", nil, { "grouped" }) 42.30 + :add_field("area.unit_id", nil, { "grouped" }) 42.31 + :add_field("area.name", nil, { "grouped" }) 42.32 + :add_where{ "area.unit_id = ?", unit.id } 42.33 + :add_where{ "area.active" } 42.34 + :add_order_by("area.name") 42.35 + 42.36 + if member then 42.37 + areas_selector:left_join ( 42.38 + "membership", nil, 42.39 + { "membership.area_id = area.id AND membership.member_id = ?", member.id } 42.40 + ) 42.41 + areas_selector:add_field("membership.member_id NOTNULL", "subscribed", { "grouped" }) 42.42 + end 42.43 + 42.44 + local areas = areas_selector:exec() 42.45 + if member then 42.46 + areas:load_delegation_info_once_for_member_id(member.id) 42.47 + end 42.48 + 42.49 + if #areas > 0 then 42.50 + 42.51 + ui.container { 42.52 + attr = { class = "sidebarHead" }, 42.53 + content = function () 42.54 + ui.heading { level = 2, content = function () 42.55 + ui.link { 42.56 + attr = { class = "unit" }, 42.57 + module = "unit", view = "show", id = unit.id, 42.58 + content = unit.name 42.59 + } 42.60 + 42.61 + if member then 42.62 + local delegation = Delegation:by_pk(member.id, unit.id, nil, nil) 42.63 + 42.64 + if delegation then 42.65 + ui.link { 42.66 + module = "delegation", view = "show", params = { 42.67 + unit_id = unit.id 42.68 + }, 42.69 + attr = { class = "delegation_info" }, 42.70 + content = function () 42.71 + ui.delegation(delegation.trustee_id, delegation.trustee.name) 42.72 + end 42.73 + } 42.74 + end 42.75 + end 42.76 + end } 42.77 + 42.78 + end 42.79 + } 42.80 + 42.81 + 42.82 + ui.tag { tag = "div", attr = { class = "areas areas-" .. unit.id }, content = function () 42.83 + 42.84 + local any_subscribed = false 42.85 + local subscribed_count = 0 42.86 + for i, area in ipairs(areas) do 42.87 + 42.88 + local class = "sidebarRow" 42.89 + class = class .. (not area.subscribed and " disabled" or "") 42.90 + 42.91 + ui.tag { tag = "div", attr = { class = class }, content = function () 42.92 + 42.93 + if area.subscribed then 42.94 + local text = _"subscribed" 42.95 + ui.image { attr = { class = "icon24 star", alt = text, title = text }, static = "icons/48/star.png" } 42.96 + any_subscribed = true 42.97 + subscribed_count = subscribed_count +1 42.98 + end 42.99 + 42.100 + if member then 42.101 + local delegation = Delegation:by_pk(member.id, nil, area.id, nil) 42.102 + 42.103 + if delegation then 42.104 + ui.link { 42.105 + module = "delegation", view = "show", params = { 42.106 + area_id = area.id 42.107 + }, 42.108 + attr = { class = "delegation_info" }, 42.109 + content = function () 42.110 + ui.delegation(delegation.trustee_id, delegation.trustee_id and delegation.trustee.name) 42.111 + end 42.112 + } 42.113 + end 42.114 + end 42.115 + 42.116 + slot.put ( " " ) 42.117 + 42.118 + ui.link { 42.119 + attr = { class = "area" }, 42.120 + module = "area", view = "show", id = area.id, 42.121 + content = area.name 42.122 + } 42.123 + 42.124 + 42.125 + end } 42.126 + end 42.127 + if subscribed_count < #areas then 42.128 + local text 42.129 + if any_subscribed then 42.130 + text = _"show other subject areas" 42.131 + else 42.132 + text = _"show subject areas" 42.133 + end 42.134 + ui.script{ script = "$('.areas-" .. unit.id .. "').addClass('folded');" } 42.135 + ui.tag { tag = "div", attr = { class = "sidebarRow moreLink whenfolded" }, content = function () 42.136 + ui.link { 42.137 + attr = { 42.138 + onclick = "$('.areas-" .. unit.id .. "').removeClass('folded'); return false;" 42.139 + }, 42.140 + text = text 42.141 + } 42.142 + end } 42.143 + ui.tag { tag = "div", attr = { class = "sidebarRow moreLink whenunfolded" }, content = function () 42.144 + ui.link { 42.145 + attr = { 42.146 + onclick = "$('.areas-" .. unit.id .. "').addClass('folded'); return false;" 42.147 + }, 42.148 + text = _"collapse subject areas" 42.149 + } 42.150 + end } 42.151 + end 42.152 + end } 42.153 + end 42.154 + end ) 42.155 +end 42.156 + 42.157 +
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/app/main/index/_sidebar_whatcanido.lua Thu Jul 10 01:19:48 2014 +0200 43.3 @@ -0,0 +1,71 @@ 43.4 +ui.sidebar ( "tab-whatcanido", function () 43.5 + 43.6 + ui.sidebarHeadWhatCanIDo() 43.7 + 43.8 + if app.session.member then 43.9 + ui.sidebarSection( function() 43.10 + ui.heading { level = 3, content = _"I want to know whats going on" } 43.11 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.12 + ui.tag { tag = "li", content = _"take a look on the issues (see left)" } 43.13 + ui.tag { tag = "li", content = _"by default only those issues are shown, for which your are eligible to participate (change filters on top of the list)" } 43.14 + end } 43.15 + end ) 43.16 + ui.sidebarSection( function() 43.17 + ui.heading { level = 3, content = _"I want to stay informed" } 43.18 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.19 + ui.tag { tag = "li", content = function () 43.20 + ui.tag{ content = _"check your " } 43.21 + ui.link{ 43.22 + module = "member", view = "settings_notification", 43.23 + params = { return_to = "home" }, 43.24 + text = _"notifications settings" 43.25 + } 43.26 + end } 43.27 + ui.tag { tag = "li", content = function () 43.28 + ui.tag{ content = _"subscribe subject areas or add your interested to issues and you will be notified about changes (follow the instruction on the area or issue page)" } 43.29 + end } 43.30 + end } 43.31 + end ) 43.32 + ui.sidebarSection( function() 43.33 + ui.heading { level = 3, content = _"I want to start a new initiative" } 43.34 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.35 + ui.tag { tag = "li", content = _"open the appropriate subject area for your issue and follow the instruction on that page." } 43.36 + end } 43.37 + end ) 43.38 + ui.sidebarSection( function() 43.39 + ui.heading { level = 3, content = _"I want to delegate my vote" } 43.40 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.41 + ui.tag { tag = "li", content = _"open the organizational unit, subject area or issue you like to delegate and follow the instruction on that page." } 43.42 + end } 43.43 + end ) 43.44 + ui.sidebarSection( function() 43.45 + ui.heading { level = 3, content = _"I want to take a look at other organizational units" } 43.46 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.47 + ui.tag { tag = "li", content = function () 43.48 + ui.link{ 43.49 + module = "unit", view = "list", 43.50 + text = _"show all units" 43.51 + } 43.52 + end } 43.53 + end } 43.54 + end ) 43.55 + ui.sidebarSection( function() 43.56 + ui.heading { level = 3, content = _"I want to learn more about LiquidFeedback" } 43.57 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 43.58 + ui.tag { tag = "li", content = function() 43.59 + ui.link { module = "help", view = "introduction", content = _"structured discussion" } 43.60 + end } 43.61 + ui.tag { tag = "li", content = function() 43.62 + ui.link { module = "help", view = "introduction", content = _"4 phases of a decision" } 43.63 + end } 43.64 + ui.tag { tag = "li", content = function() 43.65 + ui.link { module = "help", view = "introduction", content = _"vote delegation" } 43.66 + end } 43.67 + ui.tag { tag = "li", content = function() 43.68 + ui.link { module = "help", view = "introduction", content = _"preference voting" } 43.69 + end } 43.70 + end } 43.71 + end ) 43.72 + end 43.73 + 43.74 +end )
44.1 --- a/app/main/index/about.lua Thu Jul 10 01:02:43 2014 +0200 44.2 +++ b/app/main/index/about.lua Thu Jul 10 01:19:48 2014 +0200 44.3 @@ -1,102 +1,91 @@ 44.4 ui.title(_"About site") 44.5 44.6 -if app.session.member_id and config.use_terms then 44.7 - ui.actions(function() 44.8 - ui.link{ 44.9 - module = "index", 44.10 - view = "usage_terms", 44.11 - text = _"Terms of use" 44.12 - } 44.13 - end) 44.14 -end 44.15 +ui.section( function() 44.16 44.17 + ui.sectionHead( function() 44.18 + ui.heading{ level = 1, content = _"About site" } 44.19 + end ) 44.20 + 44.21 + ui.sectionRow( function() 44.22 44.23 -slot.put("<br />") 44.24 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = _"This service is provided by:" } 44.25 -slot.put("<br />") 44.26 - 44.27 -slot.put(config.app_service_provider) 44.28 + ui.heading{ level = 3, content = _"This service is provided by:" } 44.29 + slot.put(config.app_service_provider) 44.30 44.31 -slot.put("<br />") 44.32 -slot.put("<br />") 44.33 -slot.put("<br />") 44.34 + end ) 44.35 44.36 + ui.sectionRow( function() 44.37 44.38 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = _"This service is provided using the following software components:" } 44.39 -slot.put("<br />") 44.40 + ui.heading{ level = 3, content = _"This service is provided using the following software components:" } 44.41 44.42 -local tmp = { 44.43 - { 44.44 - name = "LiquidFeedback Frontend", 44.45 - url = "http://www.public-software-group.org/liquid_feedback", 44.46 - version = config.app_version, 44.47 - license = "MIT/X11", 44.48 - license_url = "http://www.public-software-group.org/licenses" 44.49 - }, 44.50 - { 44.51 - name = "LiquidFeedback Core", 44.52 - url = "http://www.public-software-group.org/liquid_feedback", 44.53 - version = db:query("SELECT * from liquid_feedback_version;")[1].string, 44.54 - license = "MIT/X11", 44.55 - license_url = "http://www.public-software-group.org/licenses" 44.56 - }, 44.57 - { 44.58 - name = "WebMCP", 44.59 - url = "http://www.public-software-group.org/webmcp", 44.60 - version = _WEBMCP_VERSION, 44.61 - license = "MIT/X11", 44.62 - license_url = "http://www.public-software-group.org/licenses" 44.63 - }, 44.64 - { 44.65 - name = "Lua", 44.66 - url = "http://www.lua.org", 44.67 - version = _VERSION:gsub("Lua ", ""), 44.68 - license = "MIT/X11", 44.69 - license_url = "http://www.lua.org/license.html" 44.70 - }, 44.71 - { 44.72 - name = "PostgreSQL", 44.73 - url = "http://www.postgresql.org/", 44.74 - version = db:query("SELECT version();")[1].version:gsub("PostgreSQL ", ""):gsub("on.*", ""), 44.75 - license = "BSD", 44.76 - license_url = "http://www.postgresql.org/about/licence" 44.77 - }, 44.78 -} 44.79 + local tmp = { 44.80 + { 44.81 + name = "LiquidFeedback Frontend", 44.82 + url = "http://www.public-software-group.org/liquid_feedback", 44.83 + version = config.app_version, 44.84 + license = "MIT/X11", 44.85 + license_url = "http://www.public-software-group.org/licenses" 44.86 + }, 44.87 + { 44.88 + name = "LiquidFeedback Core", 44.89 + url = "http://www.public-software-group.org/liquid_feedback", 44.90 + version = db:query("SELECT * from liquid_feedback_version;")[1].string, 44.91 + license = "MIT/X11", 44.92 + license_url = "http://www.public-software-group.org/licenses" 44.93 + }, 44.94 + { 44.95 + name = "WebMCP", 44.96 + url = "http://www.public-software-group.org/webmcp", 44.97 + version = _WEBMCP_VERSION, 44.98 + license = "MIT/X11", 44.99 + license_url = "http://www.public-software-group.org/licenses" 44.100 + }, 44.101 + { 44.102 + name = "Lua", 44.103 + url = "http://www.lua.org", 44.104 + version = _VERSION:gsub("Lua ", ""), 44.105 + license = "MIT/X11", 44.106 + license_url = "http://www.lua.org/license.html" 44.107 + }, 44.108 + { 44.109 + name = "PostgreSQL", 44.110 + url = "http://www.postgresql.org/", 44.111 + version = db:query("SELECT version();")[1].version:gsub("PostgreSQL ", ""):gsub("on.*", ""), 44.112 + license = "BSD", 44.113 + license_url = "http://www.postgresql.org/about/licence" 44.114 + }, 44.115 + } 44.116 44.117 -ui.list{ 44.118 - records = tmp, 44.119 - columns = { 44.120 - { 44.121 - label = _"Software", 44.122 - content = function(record) 44.123 - ui.link{ 44.124 - content = record.name, 44.125 - external = record.url 44.126 + ui.list{ 44.127 + records = tmp, 44.128 + columns = { 44.129 + { 44.130 + content = function(record) 44.131 + ui.link{ 44.132 + content = record.name, 44.133 + external = record.url 44.134 + } 44.135 + end 44.136 + }, 44.137 + { 44.138 + content = function(record) ui.field.text{ value = record.version } end 44.139 + }, 44.140 + { 44.141 + content = function(record) 44.142 + ui.link{ 44.143 + content = record.license, 44.144 + external = record.license_url 44.145 + } 44.146 + end 44.147 + 44.148 } 44.149 - end 44.150 - }, 44.151 - { 44.152 - label = _"Version", 44.153 - content = function(record) ui.field.text{ value = record.version } end 44.154 - }, 44.155 - { 44.156 - label = _"License", 44.157 - content = function(record) 44.158 - ui.link{ 44.159 - content = record.license, 44.160 - external = record.license_url 44.161 - } 44.162 - end 44.163 + } 44.164 + } 44.165 + 44.166 + end ) 44.167 44.168 - } 44.169 - } 44.170 -} 44.171 + ui.sectionRow( function() 44.172 + ui.heading{ level = 3, content = "3rd party license information:" } 44.173 + slot.put('Some of the icons used in Liquid Feedback are from <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon set 1.3</a> by Mark James. His work is licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License.</a>') 44.174 44.175 -slot.put("<br />") 44.176 -slot.put("<br />") 44.177 -slot.put("<br />") 44.178 - 44.179 -ui.field.text{ attr = { style = "font-weight: bold;" }, value = "3rd party license information:" } 44.180 -slot.put("<br />") 44.181 -slot.put('The icons used in Liquid Feedback (except national flags) are from <a href="http://www.famfamfam.com/lab/icons/silk/">Silk icon set 1.3</a> by Mark James. His work is licensed under a <a href="http://creativecommons.org/licenses/by/2.5/">Creative Commons Attribution 2.5 License.</a>') 44.182 - 44.183 + end ) 44.184 +end )
45.1 --- a/app/main/index/check_delegations.lua Thu Jul 10 01:02:43 2014 +0200 45.2 +++ b/app/main/index/check_delegations.lua Thu Jul 10 01:19:48 2014 +0200 45.3 @@ -8,12 +8,6 @@ 45.4 end 45.5 end) 45.6 45.7 -if app.session.needs_delegation_check then 45.8 - util.help("index.check_delegations_hard", _"Check delegations") 45.9 -else 45.10 - util.help("index.check_delegations", _"Check delegations") 45.11 -end 45.12 - 45.13 ui.form{ 45.14 module = "index", action = "check_delegations", 45.15 routing = {
46.1 --- a/app/main/index/document.lua Thu Jul 10 01:02:43 2014 +0200 46.2 +++ b/app/main/index/document.lua Thu Jul 10 01:19:48 2014 +0200 46.3 @@ -15,8 +15,6 @@ 46.4 } 46.5 end) 46.6 46.7 -util.help("index.document", _"Download documents") 46.8 - 46.9 local file_list = extos.listdir(config.document_dir) 46.10 46.11 local tmp = {}
47.1 --- a/app/main/index/download.lua Thu Jul 10 01:02:43 2014 +0200 47.2 +++ b/app/main/index/download.lua Thu Jul 10 01:19:48 2014 +0200 47.3 @@ -15,12 +15,10 @@ 47.4 } 47.5 end) 47.6 47.7 -util.help("index.download", _"Download") 47.8 - 47.9 ui.container{ 47.10 attr = { class = "wiki use_terms" }, 47.11 content = function() 47.12 - slot.put(format.wiki_text(config.download_use_terms)) 47.13 + slot.put(config.download_use_terms) 47.14 end 47.15 } 47.16
48.1 --- a/app/main/index/email_unconfirmed.lua Thu Jul 10 01:02:43 2014 +0200 48.2 +++ b/app/main/index/email_unconfirmed.lua Thu Jul 10 01:19:48 2014 +0200 48.3 @@ -7,48 +7,50 @@ 48.4 :optional_object_mode() 48.5 :exec() 48.6 48.7 - slot.select("head", function() 48.8 - ui.container{ 48.9 - attr = { class = "title" }, 48.10 - content = _"Notification address unconfirmed" 48.11 - } 48.12 - end ) 48.13 + ui.title(_"Confirm notification address") 48.14 48.15 - if current then 48.16 - ui.tag{ 48.17 - tag = "div", 48.18 - content = _("You didn't confirm your email address '#{email}'. You have received an email with an activation link.", { email = app.session.member.notify_email_unconfirmed }) 48.19 - } 48.20 - else 48.21 - ui.tag{ 48.22 - tag = "div", 48.23 - content = _("You didn't confirm your email address '#{email}' within 7 days.", { email = app.session.member.notify_email_unconfirmed }) 48.24 - } 48.25 - end 48.26 - slot.put("<br />") 48.27 + ui.section( function() 48.28 + ui.sectionHead( function() 48.29 + ui.heading{ level = 1, content = _"Notification address unconfirmed" } 48.30 + end ) 48.31 + 48.32 + ui.sectionRow( function() 48.33 + if current then 48.34 + ui.tag{ 48.35 + tag = "div", 48.36 + content = _("You didn't confirm your email address '#{email}'. You have received an email with an activation link.", { email = app.session.member.notify_email_unconfirmed }) 48.37 + } 48.38 + else 48.39 + ui.tag{ 48.40 + tag = "div", 48.41 + content = _("You didn't confirm your email address '#{email}' within 7 days.", { email = app.session.member.notify_email_unconfirmed }) 48.42 + } 48.43 + end 48.44 + slot.put("<br />") 48.45 48.46 - ui.link{ 48.47 - text = _"Change email address", 48.48 - module = "member", 48.49 - view = "settings_email", 48.50 - } 48.51 - slot.put("<br />") 48.52 - slot.put("<br />") 48.53 + ui.link{ 48.54 + text = _"Change email address", 48.55 + module = "member", 48.56 + view = "settings_email", 48.57 + } 48.58 + slot.put("<br />") 48.59 + slot.put("<br />") 48.60 48.61 - ui.link{ 48.62 - text = _("Resend activation email to '#{email}'", { email = app.session.member.notify_email_unconfirmed }), 48.63 - module = "member", 48.64 - action = "update_email", 48.65 - params = { 48.66 - resend = true 48.67 - }, 48.68 - routing = { 48.69 - default = { 48.70 - mode = "redirect", 48.71 - module = "index", 48.72 - view = "index" 48.73 + ui.link{ 48.74 + text = _("Resend activation email to '#{email}'", { email = app.session.member.notify_email_unconfirmed }), 48.75 + module = "member", 48.76 + action = "update_email", 48.77 + params = { 48.78 + resend = true 48.79 + }, 48.80 + routing = { 48.81 + default = { 48.82 + mode = "redirect", 48.83 + module = "index", 48.84 + view = "index" 48.85 + } 48.86 + } 48.87 } 48.88 - } 48.89 - } 48.90 - 48.91 + end ) 48.92 + end ) 48.93 end
49.1 --- a/app/main/index/index.lua Thu Jul 10 01:02:43 2014 +0200 49.2 +++ b/app/main/index/index.lua Thu Jul 10 01:19:48 2014 +0200 49.3 @@ -1,132 +1,114 @@ 49.4 -if app.session.member_id then 49.5 - util.help("index.index", _"Home") 49.6 +function getIssuesSelector() 49.7 + return Issue:new_selector() 49.8 + :add_order_by([[ 49.9 + coalesce( 49.10 + issue.fully_frozen + issue.voting_time, 49.11 + issue.half_frozen + issue.verification_time, 49.12 + issue.accepted + issue.discussion_time, 49.13 + issue.created + issue.admission_time 49.14 + ) - now() 49.15 + ]]) 49.16 +end 49.17 49.18 - execute.view{ 49.19 - module = "index", view = "_index_member" 49.20 - } 49.21 +--[[ 49.22 +ui.title( function () 49.23 + ui.link { attr = { class = "home" }, module = "index", view = "index", text = _"Home" } 49.24 +end) 49.25 +--]] 49.26 + 49.27 +ui.title() 49.28 49.29 -elseif app.session:has_access("anonymous") then 49.30 - if config.motd_public then 49.31 - local help_text = config.motd_public 49.32 - ui.container{ 49.33 - attr = { class = "wiki motd" }, 49.34 - content = function() 49.35 - slot.put(format.wiki_text(help_text)) 49.36 - end 49.37 - } 49.38 - end 49.39 +if false then 49.40 +slot.select ( "tabs", function () 49.41 49.42 - local open_issues_selector = Issue:new_selector() 49.43 - :add_where("issue.closed ISNULL") 49.44 - :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") 49.45 - 49.46 - local closed_issues_selector = Issue:new_selector() 49.47 - :add_where("issue.closed NOTNULL") 49.48 - :add_order_by("issue.closed DESC") 49.49 - 49.50 + ui.tag { 49.51 + attr = { onclick = "showTab(0);" }, 49.52 + content = "units", 49.53 + } 49.54 + slot.put ( " " ) 49.55 + ui.tag { 49.56 + attr = { onclick = "showTab(1);" }, 49.57 + content = "timeline" 49.58 + } 49.59 + slot.put ( " " ) 49.60 + ui.tag { 49.61 + attr = { onclick = "showTab(2);" }, 49.62 + content = "what" 49.63 + } 49.64 + slot.put ( " " ) 49.65 + ui.tag { 49.66 + attr = { onclick = "showTab(3);" }, 49.67 + content = "members" 49.68 + } 49.69 49.70 - local tabs = { 49.71 - module = "index", 49.72 - view = "index" 49.73 - } 49.74 - 49.75 - tabs[#tabs+1] = { 49.76 - name = "units", 49.77 - label = _"Units", 49.78 - module = "unit", 49.79 - view = "_list" 49.80 - } 49.81 +end ) 49.82 49.83 - tabs[#tabs+1] = { 49.84 - name = "timeline", 49.85 - label = _"Latest events", 49.86 - module = "event", 49.87 - view = "_list", 49.88 - params = { global = true } 49.89 - } 49.90 +ui.script { script = [[ 49.91 + 49.92 + var tabs = ["tab1", "main", "tab2", "tab3"] 49.93 + var currentId; 49.94 + 49.95 + function showTab(id) { 49.96 + var tabId = tabs[id]; 49.97 + $('.tab').hide(); 49.98 + $('.main').hide(); 49.99 + $('.' + tabId).show(); 49.100 + currentId = id; 49.101 + }; 49.102 + 49.103 + showTab(0); 49.104 + 49.105 + $(function(){ 49.106 + // Bind the swipeHandler callback function to the swipe event on div.box 49.107 + $( "body" ).on( "swiperight", function swipeHandler( event ) { 49.108 + newId = currentId - 1; 49.109 + if (newId < 0) return; 49.110 + showTab(newId); 49.111 + } ) 49.112 + $( "body" ).on( "swipeleft", function swipeHandler( event ) { 49.113 + newId = currentId + 1; 49.114 + if (newId > tabs.length - 1) return; 49.115 + showTab(newId); 49.116 + } ) 49.117 + }); 49.118 + 49.119 +]]} 49.120 +end 49.121 49.122 - tabs[#tabs+1] = { 49.123 - name = "open", 49.124 - label = _"Open issues", 49.125 - module = "issue", 49.126 - view = "_list", 49.127 - params = { 49.128 - for_state = "open", 49.129 - issues_selector = open_issues_selector 49.130 + 49.131 +if app.session.member then 49.132 + execute.view{ module = "index", view = "_sidebar_motd_intern" } 49.133 +else 49.134 + execute.view{ module = "index", view = "_sidebar_motd_public" } 49.135 +end 49.136 + 49.137 +if app.session:has_access("anonymous") then 49.138 + -- show the units the member has voting privileges for 49.139 + execute.view { 49.140 + module = "index", view = "_sidebar_units", params = { 49.141 + member = app.session.member 49.142 } 49.143 } 49.144 - tabs[#tabs+1] = { 49.145 - name = "closed", 49.146 - label = _"Closed issues", 49.147 - module = "issue", 49.148 - view = "_list", 49.149 - params = { 49.150 - for_state = "closed", 49.151 - issues_selector = closed_issues_selector 49.152 - } 49.153 - } 49.154 - 49.155 - if app.session:has_access('all_pseudonymous') then 49.156 - tabs[#tabs+1] = { 49.157 - name = "members", 49.158 - label = _"Members", 49.159 - module = 'member', 49.160 - view = '_list', 49.161 - params = { members_selector = Member:new_selector():add_where("active") } 49.162 - } 49.163 - end 49.164 - 49.165 - ui.tabs(tabs) 49.166 - 49.167 -else 49.168 - 49.169 - if config.motd_public then 49.170 - local help_text = config.motd_public 49.171 - ui.container{ 49.172 - attr = { class = "wiki motd" }, 49.173 - content = function() 49.174 - slot.put(format.wiki_text(help_text)) 49.175 - end 49.176 - } 49.177 - end 49.178 - 49.179 - ui.tag{ tag = "p", content = _"Closed user group, please login to participate." } 49.180 +end 49.181 49.182 - ui.form{ 49.183 - attr = { class = "login" }, 49.184 - module = 'index', 49.185 - action = 'login', 49.186 - routing = { 49.187 - ok = { 49.188 - mode = 'redirect', 49.189 - module = param.get("redirect_module") or "index", 49.190 - view = param.get("redirect_view") or "index", 49.191 - id = param.get("redirect_id"), 49.192 - }, 49.193 - error = { 49.194 - mode = 'forward', 49.195 - module = 'index', 49.196 - view = 'login', 49.197 - } 49.198 - }, 49.199 - content = function() 49.200 - ui.field.text{ 49.201 - attr = { id = "username_field" }, 49.202 - label = _'login name', 49.203 - html_name = 'login', 49.204 - value = '' 49.205 - } 49.206 - ui.script{ script = 'document.getElementById("username_field").focus();' } 49.207 - ui.field.password{ 49.208 - label = _'Password', 49.209 - html_name = 'password', 49.210 - value = '' 49.211 - } 49.212 - ui.submit{ 49.213 - text = _'Login' 49.214 - } 49.215 - end 49.216 -} 49.217 +-- show the user what can be done 49.218 +execute.view { module = "index", view = "_sidebar_whatcanido" } 49.219 49.220 +-- show active members 49.221 +if app.session:has_access("all_pseudonymous") then 49.222 + execute.view{ module = "index", view = "_sidebar_members" } 49.223 end 49.224 49.225 +if app.session:has_access("anonymous") then 49.226 + 49.227 + if not app.session.member then 49.228 +-- execute.view { 49.229 +-- module = "slideshow", view = "_index" 49.230 +-- } 49.231 + end 49.232 + 49.233 + execute.view { 49.234 + module = "issue", view = "_list2", params = { } 49.235 + } 49.236 + 49.237 +end -- if app.session:has_access "anonymous" 49.238 \ No newline at end of file
50.1 --- a/app/main/index/login.lua Thu Jul 10 01:02:43 2014 +0200 50.2 +++ b/app/main/index/login.lua Thu Jul 10 01:19:48 2014 +0200 50.3 @@ -5,32 +5,47 @@ 50.4 end 50.5 } 50.6 50.7 -ui.actions() 50.8 - 50.9 ui.title(_"Login") 50.10 app.html_title.title = _"Login" 50.11 50.12 -if config.motd_public then 50.13 - local help_text = config.motd_public 50.14 - ui.container{ 50.15 - attr = { class = "wiki motd" }, 50.16 - content = function() 50.17 - slot.put(format.wiki_text(help_text)) 50.18 - end 50.19 - } 50.20 -end 50.21 +execute.view{ module = "index", view = "_sidebar_motd_public" } 50.22 + 50.23 +ui.section(function() 50.24 + 50.25 +ui.sectionHead(function() 50.26 + ui.heading{ level = 1, content = _"Login" } 50.27 + ui.container { attr = { class = "right" }, content = function() 50.28 + for i, lang in ipairs(config.enabled_languages) do 50.29 50.30 -if app.session:has_access("anonymous") then 50.31 - ui.tag{ 50.32 - tag = 'p', 50.33 - content = _'You need to be logged in, to use all features of this system.' 50.34 - } 50.35 -else 50.36 - ui.tag{ tag = "p", content = _"Closed user group, please login to participate." } 50.37 -end 50.38 - 50.39 + locale.do_with({ lang = lang }, function() 50.40 + langcode = _("[Name of Language]") 50.41 + end) 50.42 + 50.43 + if i > 1 then 50.44 + slot.put(" | ") 50.45 + end 50.46 + 50.47 + ui.link{ 50.48 + content = function() 50.49 + ui.tag{ content = langcode } 50.50 + end, 50.51 + module = "index", 50.52 + action = "set_lang", 50.53 + params = { lang = lang }, 50.54 + routing = { 50.55 + default = { 50.56 + mode = "redirect", 50.57 + module = request.get_module(), 50.58 + view = request.get_view(), 50.59 + id = param.get_id_cgi(), 50.60 + params = param.get_all_cgi() 50.61 + } 50.62 + } 50.63 + } 50.64 + end 50.65 + end } 50.66 +end) 50.67 ui.form{ 50.68 - attr = { class = "login" }, 50.69 module = 'index', 50.70 action = 'login', 50.71 routing = { 50.72 @@ -47,22 +62,36 @@ 50.73 } 50.74 }, 50.75 content = function() 50.76 - ui.field.text{ 50.77 - attr = { id = "username_field" }, 50.78 - label = _'login name', 50.79 - html_name = 'login', 50.80 - value = '' 50.81 - } 50.82 - ui.script{ script = 'document.getElementById("username_field").focus();' } 50.83 - ui.field.password{ 50.84 - label = _'Password', 50.85 - html_name = 'password', 50.86 - value = '' 50.87 - } 50.88 - ui.submit{ 50.89 - text = _'Login' 50.90 - } 50.91 - slot.put(" ") 50.92 - ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" } 50.93 + ui.sectionRow(function() 50.94 + ui.field.text{ 50.95 + attr = { id = "username_field" }, 50.96 + label = _'Login name', 50.97 + name = 'login', 50.98 + value = '' 50.99 + } 50.100 + ui.script{ script = 'document.getElementById("username_field").focus();' } 50.101 + ui.field.password{ 50.102 + label = _'Password', 50.103 + name = 'password', 50.104 + value = '' 50.105 + } 50.106 + ui.container { attr = { class = "actions" }, content = function() 50.107 + ui.tag{ 50.108 + tag = "input", 50.109 + attr = { 50.110 + type = "submit", 50.111 + class = "btn btn-default", 50.112 + value = _'Login' 50.113 + }, 50.114 + content = "" 50.115 + } 50.116 + slot.put("<br />") 50.117 + slot.put("<br />") 50.118 + ui.link{ module = "index", view = "reset_password", text = _"Forgot password?" } 50.119 + slot.put(" ") 50.120 + ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" } 50.121 + end } 50.122 + end ) 50.123 end 50.124 } 50.125 +end ) 50.126 \ No newline at end of file
51.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 51.2 +++ b/app/main/index/notifications.lua Thu Jul 10 01:19:48 2014 +0200 51.3 @@ -0,0 +1,14 @@ 51.4 +if app.session.member then 51.5 + ui.title(_"Notifications") 51.6 + 51.7 + ui.section( function() 51.8 + 51.9 + ui.sectionHead( function() 51.10 + ui.heading{ level = 1, content = _"Notifications" } 51.11 + end ) 51.12 + 51.13 + ui.sectionRow( function() 51.14 + execute.view { module = "index", view = "_sidebar_notifications" } 51.15 + end ) 51.16 + end ) 51.17 +end
52.1 --- a/app/main/index/register.lua Thu Jul 10 01:02:43 2014 +0200 52.2 +++ b/app/main/index/register.lua Thu Jul 10 01:19:48 2014 +0200 52.3 @@ -7,7 +7,7 @@ 52.4 local login = param.get("login") 52.5 52.6 ui.form{ 52.7 - attr = { class = "vertical" }, 52.8 + attr = { class = "section vertical" }, 52.9 module = 'index', 52.10 action = 'register', 52.11 params = { 52.12 @@ -19,30 +19,27 @@ 52.13 content = function() 52.14 52.15 if not code then 52.16 + ui.field.hidden{ name = "step", value = 1 } 52.17 ui.title(_"Registration (step 1 of 3: Invite code)") 52.18 - ui.actions(function() 52.19 + ui.sectionHead( function() 52.20 + ui.heading { level = 1, content = _"Please enter the invite code you've received" } 52.21 + end ) 52.22 + ui.sectionRow( function() 52.23 + ui.field.text{ 52.24 + label = _'Invite code', 52.25 + name = 'code', 52.26 + value = param.get("invite") 52.27 + } 52.28 + ui.submit{ 52.29 + text = _'proceed with registration' 52.30 + } 52.31 + slot.put(" ") 52.32 ui.link{ 52.33 - content = function() 52.34 - slot.put(_"Cancel registration") 52.35 - end, 52.36 + content = _"cancel registration", 52.37 module = "index", 52.38 view = "index" 52.39 } 52.40 - end) 52.41 - ui.field.hidden{ name = "step", value = 1 } 52.42 - ui.tag{ 52.43 - tag = "p", 52.44 - content = _"Please enter the invite code you've received." 52.45 - } 52.46 - ui.field.text{ 52.47 - label = _'Invite code', 52.48 - name = 'code', 52.49 - value = param.get("invite") 52.50 - } 52.51 - ui.submit{ 52.52 - text = _'Proceed with registration' 52.53 - } 52.54 - 52.55 + end ) 52.56 else 52.57 local member = Member:new_selector() 52.58 :add_where{ "invite_code = ?", code } 52.59 @@ -53,79 +50,145 @@ 52.60 if not member.notify_email and not notify_email or not member.name and not name or not member.login and not login or step == 1 then 52.61 ui.title(_"Registration (step 2 of 3: Personal information)") 52.62 ui.field.hidden{ name = "step", value = 2 } 52.63 - ui.actions(function() 52.64 + 52.65 + ui.sectionHead( function() 52.66 + ui.heading { level = 1, content = _"Check and enter personal data" } 52.67 + end ) 52.68 + ui.sectionRow( function() 52.69 + ui.tag{ 52.70 + tag = "p", 52.71 + content = _"This invite key is connected with the following information:" 52.72 + } 52.73 + 52.74 + execute.view{ module = "member", view = "_profile", params = { member = member, for_registration = true } } 52.75 + 52.76 + if not config.locked_profile_fields.notify_email then 52.77 + ui.tag{ 52.78 + tag = "p", 52.79 + content = _"Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link." 52.80 + } 52.81 + ui.field.text{ 52.82 + label = _'Email address', 52.83 + name = 'notify_email', 52.84 + value = param.get("notify_email") or member.notify_email 52.85 + } 52.86 + end 52.87 + if not config.locked_profile_fields.name then 52.88 + ui.tag{ 52.89 + tag = "p", 52.90 + content = _"Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you." 52.91 + } 52.92 + ui.field.text{ 52.93 + label = _'Screen name', 52.94 + name = 'name', 52.95 + value = param.get("name") or member.name 52.96 + } 52.97 + end 52.98 + if not config.locked_profile_fields.login then 52.99 + ui.tag{ 52.100 + tag = "p", 52.101 + content = _"Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive." 52.102 + } 52.103 + ui.field.text{ 52.104 + label = _'Login name', 52.105 + name = 'login', 52.106 + value = param.get("login") or member.login 52.107 + } 52.108 + end 52.109 + ui.submit{ 52.110 + text = _'proceed with registration' 52.111 + } 52.112 + slot.put(" ") 52.113 ui.link{ 52.114 - content = function() 52.115 - slot.put(_"One step back") 52.116 - end, 52.117 + content = _"one step back", 52.118 module = "index", 52.119 view = "register", 52.120 params = { 52.121 invite = code 52.122 } 52.123 } 52.124 - slot.put(" · ") 52.125 + slot.put(" ") 52.126 ui.link{ 52.127 - content = function() 52.128 - slot.put(_"Cancel registration") 52.129 - end, 52.130 + content = _"cancel registration", 52.131 module = "index", 52.132 view = "index" 52.133 } 52.134 - end) 52.135 - 52.136 - ui.tag{ 52.137 - tag = "p", 52.138 - content = _"This invite key is connected with the following information:" 52.139 - } 52.140 - 52.141 - execute.view{ module = "member", view = "_profile", params = { member = member, include_private_data = true } } 52.142 - 52.143 - if not config.locked_profile_fields.notify_email then 52.144 - ui.tag{ 52.145 - tag = "p", 52.146 - content = _"Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link." 52.147 - } 52.148 - ui.field.text{ 52.149 - label = _'Email address', 52.150 - name = 'notify_email', 52.151 - value = param.get("notify_email") or member.notify_email 52.152 - } 52.153 - end 52.154 - if not config.locked_profile_fields.name then 52.155 - ui.tag{ 52.156 - tag = "p", 52.157 - content = _"Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you." 52.158 - } 52.159 - ui.field.text{ 52.160 - label = _'Screen name', 52.161 - name = 'name', 52.162 - value = param.get("name") or member.name 52.163 - } 52.164 - end 52.165 - if not config.locked_profile_fields.login then 52.166 - ui.tag{ 52.167 - tag = "p", 52.168 - content = _"Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive." 52.169 - } 52.170 - ui.field.text{ 52.171 - label = _'Login name', 52.172 - name = 'login', 52.173 - value = param.get("login") or member.login 52.174 - } 52.175 - end 52.176 - ui.submit{ 52.177 - text = _'Proceed with registration' 52.178 - } 52.179 + end ) 52.180 else 52.181 52.182 ui.field.hidden{ name = "step", value = "3" } 52.183 ui.title(_"Registration (step 3 of 3: Terms of use and password)") 52.184 - ui.actions(function() 52.185 - ui.link{ 52.186 + ui.sectionHead( function() 52.187 + ui.heading { level = 1, content = _"Read and accept the terms and choose a password" } 52.188 + end ) 52.189 + ui.sectionRow( function() 52.190 + ui.container{ 52.191 + attr = { class = "wiki use_terms" }, 52.192 content = function() 52.193 - slot.put(_"One step back") 52.194 - end, 52.195 + slot.put(config.use_terms) 52.196 + end 52.197 + } 52.198 + 52.199 + member.notify_email = notify_email or member.notify_email 52.200 + member.name = name or member.name 52.201 + member.login = login or member.login 52.202 + 52.203 + execute.view{ module = "member", view = "_profile", params = { 52.204 + member = member, include_private_data = true 52.205 + } } 52.206 + 52.207 + for i, checkbox in ipairs(config.use_terms_checkboxes) do 52.208 + slot.put("<br />") 52.209 + ui.tag{ 52.210 + tag = "div", 52.211 + content = function() 52.212 + ui.tag{ 52.213 + tag = "input", 52.214 + attr = { 52.215 + type = "checkbox", 52.216 + id = "use_terms_checkbox_" .. checkbox.name, 52.217 + name = "use_terms_checkbox_" .. checkbox.name, 52.218 + value = "1", 52.219 + style = "float: left;", 52.220 + checked = param.get("use_terms_checkbox_" .. checkbox.name, atom.boolean) and "checked" or nil 52.221 + } 52.222 + } 52.223 + slot.put(" ") 52.224 + ui.tag{ 52.225 + tag = "label", 52.226 + attr = { ['for'] = "use_terms_checkbox_" .. checkbox.name }, 52.227 + content = function() slot.put(checkbox.html) end 52.228 + } 52.229 + end 52.230 + } 52.231 + end 52.232 + 52.233 + slot.put("<br />") 52.234 + 52.235 + ui.tag{ 52.236 + tag = "p", 52.237 + content = _"Please choose a password and enter it twice. The password is case sensitive." 52.238 + } 52.239 + ui.field.text{ 52.240 + readonly = true, 52.241 + label = _'Login name', 52.242 + name = 'login', 52.243 + value = member.login 52.244 + } 52.245 + ui.field.password{ 52.246 + label = _'Password', 52.247 + name = 'password1', 52.248 + } 52.249 + ui.field.password{ 52.250 + label = _'Password (repeat)', 52.251 + name = 'password2', 52.252 + } 52.253 + ui.submit{ 52.254 + text = _'activate account' 52.255 + } 52.256 + slot.put(" ") 52.257 + ui.link{ 52.258 + content = _"one step back", 52.259 module = "index", 52.260 view = "register", 52.261 params = { 52.262 @@ -136,83 +199,13 @@ 52.263 step = 1 52.264 } 52.265 } 52.266 - slot.put(" · ") 52.267 + slot.put(" ") 52.268 ui.link{ 52.269 - content = function() 52.270 - slot.put(_"Cancel registration") 52.271 - end, 52.272 + content = _"cancel registration", 52.273 module = "index", 52.274 view = "index" 52.275 } 52.276 - end) 52.277 - ui.container{ 52.278 - attr = { class = "wiki use_terms" }, 52.279 - content = function() 52.280 - if config.use_terms_html then 52.281 - slot.put(config.use_terms_html) 52.282 - else 52.283 - slot.put(format.wiki_text(config.use_terms)) 52.284 - end 52.285 - end 52.286 - } 52.287 - 52.288 - member.notify_email = notify_email or member.notify_email 52.289 - member.name = name or member.name 52.290 - member.login = login or member.login 52.291 - 52.292 - execute.view{ module = "member", view = "_profile", params = { 52.293 - member = member, include_private_data = true 52.294 - } } 52.295 - 52.296 - for i, checkbox in ipairs(config.use_terms_checkboxes) do 52.297 - slot.put("<br />") 52.298 - ui.tag{ 52.299 - tag = "div", 52.300 - content = function() 52.301 - ui.tag{ 52.302 - tag = "input", 52.303 - attr = { 52.304 - type = "checkbox", 52.305 - id = "use_terms_checkbox_" .. checkbox.name, 52.306 - name = "use_terms_checkbox_" .. checkbox.name, 52.307 - value = "1", 52.308 - style = "float: left;", 52.309 - checked = param.get("use_terms_checkbox_" .. checkbox.name, atom.boolean) and "checked" or nil 52.310 - } 52.311 - } 52.312 - slot.put(" ") 52.313 - ui.tag{ 52.314 - tag = "label", 52.315 - attr = { ['for'] = "use_terms_checkbox_" .. checkbox.name }, 52.316 - content = function() slot.put(checkbox.html) end 52.317 - } 52.318 - end 52.319 - } 52.320 - end 52.321 - 52.322 - slot.put("<br />") 52.323 - 52.324 - ui.tag{ 52.325 - tag = "p", 52.326 - content = _"Please choose a password and enter it twice. The password is case sensitive." 52.327 - } 52.328 - ui.field.text{ 52.329 - readonly = true, 52.330 - label = _'Login name', 52.331 - name = 'login', 52.332 - value = member.login 52.333 - } 52.334 - ui.field.password{ 52.335 - label = _'Password', 52.336 - name = 'password1', 52.337 - } 52.338 - ui.field.password{ 52.339 - label = _'Password (repeat)', 52.340 - name = 'password2', 52.341 - } 52.342 - ui.submit{ 52.343 - text = _'Activate account' 52.344 - } 52.345 + end ) 52.346 end 52.347 end 52.348 end
53.1 --- a/app/main/index/reset_password.lua Thu Jul 10 01:02:43 2014 +0200 53.2 +++ b/app/main/index/reset_password.lua Thu Jul 10 01:19:48 2014 +0200 53.3 @@ -2,83 +2,123 @@ 53.4 53.5 ui.title(_"Reset password") 53.6 53.7 -ui.actions(function() 53.8 - ui.link{ 53.9 - content = function() 53.10 - slot.put(_"Cancel") 53.11 - end, 53.12 - module = "index", 53.13 - view = "login" 53.14 - } 53.15 -end) 53.16 +ui.section( function() 53.17 + 53.18 + ui.sectionHead( function() 53.19 + ui.heading{ level = 1, content = _"Reset password" } 53.20 + end ) 53.21 + 53.22 + ui.sectionRow( function() 53.23 53.24 53.25 -local secret = param.get("secret") 53.26 + local secret = param.get("secret") 53.27 53.28 -if not secret then 53.29 - ui.tag{ 53.30 - tag = 'p', 53.31 - content = _'Please enter your login name. You will receive an email with a link to reset your password.' 53.32 - } 53.33 - ui.form{ 53.34 - attr = { class = "vertical" }, 53.35 - module = "index", 53.36 - action = "reset_password", 53.37 - routing = { 53.38 - ok = { 53.39 - mode = "redirect", 53.40 - module = "index", 53.41 - view = "index" 53.42 - } 53.43 - }, 53.44 - content = function() 53.45 - ui.field.text{ 53.46 - label = _"login name", 53.47 - name = "login" 53.48 - } 53.49 - ui.submit{ text = _"Request password reset link" } 53.50 - slot.put(" ") 53.51 - ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" } 53.52 - end 53.53 - } 53.54 - 53.55 -else 53.56 - 53.57 - ui.form{ 53.58 - attr = { class = "vertical" }, 53.59 - module = "index", 53.60 - action = "reset_password", 53.61 - routing = { 53.62 - ok = { 53.63 - mode = "redirect", 53.64 - module = "index", 53.65 - view = "index" 53.66 - } 53.67 - }, 53.68 - content = function() 53.69 + if not secret then 53.70 ui.tag{ 53.71 tag = 'p', 53.72 - content = _'Please enter the email reset code you have received:' 53.73 + content = _'Please enter your login name. You will receive an email with a link to reset your password.' 53.74 } 53.75 - ui.field.text{ 53.76 - label = _"Reset code", 53.77 - name = "secret", 53.78 - value = secret 53.79 - } 53.80 - ui.tag{ 53.81 - tag = 'p', 53.82 - content = _'Please enter your new password twice.' 53.83 + ui.form{ 53.84 + attr = { class = "vertical" }, 53.85 + module = "index", 53.86 + action = "reset_password", 53.87 + routing = { 53.88 + ok = { 53.89 + mode = "redirect", 53.90 + module = "index", 53.91 + view = "index" 53.92 + } 53.93 + }, 53.94 + content = function() 53.95 + ui.field.text{ 53.96 + label = _"login name", 53.97 + name = "login" 53.98 + } 53.99 + 53.100 + ui.container { attr = { class = "actions" }, content = function() 53.101 + ui.tag{ 53.102 + tag = "input", 53.103 + attr = { 53.104 + type = "submit", 53.105 + class = "btn btn-default", 53.106 + value = _"Request password reset link" 53.107 + }, 53.108 + content = "" 53.109 + } 53.110 + slot.put("<br /><br />") 53.111 + ui.link{ module = "index", view = "send_login", text = _"Forgot login name?" } 53.112 + slot.put(" ") 53.113 + ui.link{ 53.114 + content = function() 53.115 + slot.put(_"Cancel") 53.116 + end, 53.117 + module = "index", 53.118 + view = "login" 53.119 + } 53.120 + end } 53.121 + end 53.122 } 53.123 - ui.field.password{ 53.124 - label = "New password", 53.125 - name = "password1" 53.126 + 53.127 + else 53.128 + 53.129 + ui.form{ 53.130 + attr = { class = "vertical" }, 53.131 + module = "index", 53.132 + action = "reset_password", 53.133 + routing = { 53.134 + ok = { 53.135 + mode = "redirect", 53.136 + module = "index", 53.137 + view = "index" 53.138 + } 53.139 + }, 53.140 + content = function() 53.141 + ui.tag{ 53.142 + tag = 'p', 53.143 + content = _'Please enter the email reset code you have received:' 53.144 + } 53.145 + ui.field.text{ 53.146 + label = _"Reset code", 53.147 + name = "secret", 53.148 + value = secret 53.149 + } 53.150 + ui.tag{ 53.151 + tag = 'p', 53.152 + content = _'Please enter your new password twice.' 53.153 + } 53.154 + ui.field.password{ 53.155 + label = "New password", 53.156 + name = "password1" 53.157 + } 53.158 + ui.field.password{ 53.159 + label = "New password (repeat)", 53.160 + name = "password2" 53.161 + } 53.162 + 53.163 + ui.container { attr = { class = "actions" }, content = function() 53.164 + ui.tag{ 53.165 + tag = "input", 53.166 + attr = { 53.167 + type = "submit", 53.168 + class = "btn btn-default", 53.169 + value = _"Save new password" 53.170 + }, 53.171 + content = "" 53.172 + } 53.173 + slot.put("<br />") 53.174 + slot.put("<br />") 53.175 + 53.176 + ui.link{ 53.177 + content = function() 53.178 + slot.put(_"Cancel") 53.179 + end, 53.180 + module = "index", 53.181 + view = "login" 53.182 + } 53.183 + end } 53.184 + end 53.185 } 53.186 - ui.field.password{ 53.187 - label = "New password (repeat)", 53.188 - name = "password2" 53.189 - } 53.190 - ui.submit{ text = _"Set new password" } 53.191 + 53.192 end 53.193 - } 53.194 - 53.195 -end 53.196 \ No newline at end of file 53.197 + end ) 53.198 +end ) 53.199 \ No newline at end of file
54.1 --- a/app/main/index/search.lua Thu Jul 10 01:02:43 2014 +0200 54.2 +++ b/app/main/index/search.lua Thu Jul 10 01:19:48 2014 +0200 54.3 @@ -1,65 +1,104 @@ 54.4 local search_for = param.get("search_for", atom.string) or "global" 54.5 -local search_string = param.get("search", atom.string) 54.6 +local search_string = param.get("q", atom.string) 54.7 54.8 if search_string then 54.9 - slot.put_into("title", encode.html(_("Search results for: '#{search}'", { search = search_string }))) 54.10 + ui.title ( _("Search results for: '#{search}'", { search = search_string } ) ) 54.11 else 54.12 - slot.put_into("title", encode.html(_"Search")) 54.13 + ui.title ( _"Search" ) 54.14 end 54.15 54.16 ui.form{ 54.17 method = "get", module = "index", view = "search", 54.18 routing = { default = { mode = "redirect", 54.19 - module = "index", view = "search", search_for = search_for, search = search_string 54.20 + module = "index", view = "search", search_for = search_for, q = search_string 54.21 } }, 54.22 - attr = { class = "vertical" }, 54.23 + attr = { class = "vertical section" }, 54.24 content = function() 54.25 - 54.26 - if app.session:has_access("everything") then 54.27 - ui.field.select{ 54.28 - label = _"Search context", 54.29 - name = "search_for", 54.30 - value = search_for, 54.31 - foreign_records = { 54.32 - { id = "global", name = _"Global search" }, 54.33 - { id = "member", name = _"Search for members" }, 54.34 - { id = "issue", name = _"Search for issues" } 54.35 - }, 54.36 - foreign_id = "id", 54.37 - foreign_name = "name", 54.38 + 54.39 + ui.sectionHead( function() 54.40 + ui.heading { level = 1, content = _"Search" } 54.41 + end) 54.42 + 54.43 + ui.sectionRow( function() 54.44 + ui.tag { content = _"Search term (only complete words)" } 54.45 + ui.tag { 54.46 + tag = "input", 54.47 + attr = { 54.48 + name = "q", 54.49 + value = search_string 54.50 + } 54.51 } 54.52 - end 54.53 - ui.field.text{ label = _"Search term (only complete words)", name = "search", value = search_string } 54.54 - ui.submit{ value = _"Start search" } 54.55 + ui.tag{ 54.56 + tag = "input", 54.57 + attr = { 54.58 + class = "btn btn-search", 54.59 + type = "submit", 54.60 + value = _"search" 54.61 + } 54.62 + } 54.63 + end ) 54.64 end 54.65 } 54.66 54.67 -slot.put("<br />") 54.68 54.69 -if search_string then 54.70 +if not search_string then 54.71 + return 54.72 +end 54.73 + 54.74 54.75 - if app.session:has_access("everything") then 54.76 - if search_for == "global" or search_for == "member" then 54.77 - local members_selector = Member:get_search_selector(search_string) 54.78 +local members_selector = Member:get_search_selector(search_string) 54.79 +local count = members_selector:count() 54.80 +local text 54.81 +if count == 0 then 54.82 + text = _"No matching members found" 54.83 +elseif count == 1 then 54.84 + text = _"1 matching member found" 54.85 +else 54.86 + text = _"#{count} matching members found" 54.87 +end 54.88 +if app.session:has_access("everything") then 54.89 + ui.section( function() 54.90 + ui.sectionHead( function() 54.91 + ui.heading { level = 1, content = _(text, { count = count }) } 54.92 + end ) 54.93 + if count > 0 then 54.94 execute.view{ 54.95 module = "member", 54.96 view = "_list", 54.97 - params = { members_selector = members_selector }, 54.98 + params = { 54.99 + members_selector = members_selector, 54.100 + no_filter = true 54.101 + }, 54.102 } 54.103 end 54.104 - end 54.105 + end ) 54.106 +end 54.107 + 54.108 +slot.put("<br />") 54.109 + 54.110 +local issues_selector = Issue:get_search_selector(search_string) 54.111 +local count = issues_selector:count() 54.112 +local text 54.113 +if count == 0 then 54.114 + text = _"No matching issues found" 54.115 +elseif count == 1 then 54.116 + text = _"1 matching issue found" 54.117 +else 54.118 + text = _"#{count} matching issues found" 54.119 +end 54.120 54.121 - if search_for == "global" or search_for == "issue" then 54.122 - local issues_selector = Issue:get_search_selector(search_string) 54.123 +ui.section( function() 54.124 + ui.sectionHead( function() 54.125 + ui.heading { level = 1, content = _(text, { count = count }) } 54.126 + end ) 54.127 + if count > 0 then 54.128 execute.view{ 54.129 module = "issue", 54.130 - view = "_list", 54.131 + view = "_list2", 54.132 params = { 54.133 - issues_selector = issues_selector, 54.134 - highlight_string = search_string, 54.135 + search = search_string, 54.136 no_filter = true 54.137 }, 54.138 } 54.139 end 54.140 - 54.141 -end 54.142 +end)
55.1 --- a/app/main/index/send_login.lua Thu Jul 10 01:02:43 2014 +0200 55.2 +++ b/app/main/index/send_login.lua Thu Jul 10 01:19:48 2014 +0200 55.3 @@ -1,35 +1,54 @@ 55.4 -ui.title(_"Request email with login name") 55.5 +ui.title(_"Recover login name") 55.6 + 55.7 +ui.section( function() 55.8 55.9 -ui.actions(function() 55.10 - ui.link{ 55.11 - content = function() 55.12 - slot.put(_"Cancel") 55.13 - end, 55.14 - module = "index", 55.15 - view = "login" 55.16 - } 55.17 -end) 55.18 + ui.sectionHead( function() 55.19 + ui.heading{ level = 1, content = _"Request email with login name" } 55.20 + end ) 55.21 + 55.22 + ui.sectionRow( function() 55.23 55.24 -ui.tag{ 55.25 - tag = 'p', 55.26 - content = _'Please enter your email address. You will receive an email with your login name.' 55.27 -} 55.28 -ui.form{ 55.29 - attr = { class = "vertical" }, 55.30 - module = "index", 55.31 - action = "send_login", 55.32 - routing = { 55.33 - ok = { 55.34 - mode = "redirect", 55.35 + ui.tag{ 55.36 + tag = 'p', 55.37 + content = _'Please enter your email address. You will receive an email with your login name.' 55.38 + } 55.39 + ui.form{ 55.40 + attr = { class = "vertical" }, 55.41 module = "index", 55.42 - view = "index" 55.43 + action = "send_login", 55.44 + routing = { 55.45 + ok = { 55.46 + mode = "redirect", 55.47 + module = "index", 55.48 + view = "index" 55.49 + } 55.50 + }, 55.51 + content = function() 55.52 + ui.field.text{ 55.53 + label = _"Email address", 55.54 + name = "email" 55.55 + } 55.56 + 55.57 + ui.container { attr = { class = "actions" }, content = function() 55.58 + ui.tag{ 55.59 + tag = "input", 55.60 + attr = { 55.61 + type = "submit", 55.62 + class = "btn btn-default", 55.63 + value = _"Request email with login name" 55.64 + }, 55.65 + content = "" 55.66 + } 55.67 + slot.put("<br /><br />") 55.68 + ui.link{ 55.69 + content = function() 55.70 + slot.put(_"Cancel") 55.71 + end, 55.72 + module = "index", 55.73 + view = "login" 55.74 + } 55.75 + end } 55.76 + end 55.77 } 55.78 - }, 55.79 - content = function() 55.80 - ui.field.text{ 55.81 - label = _"Email address", 55.82 - name = "email" 55.83 - } 55.84 - ui.submit{ text = _"Request email with login name" } 55.85 - end 55.86 -} 55.87 + end ) 55.88 +end ) 55.89 \ No newline at end of file
56.1 --- a/app/main/index/usage_terms.lua Thu Jul 10 01:02:43 2014 +0200 56.2 +++ b/app/main/index/usage_terms.lua Thu Jul 10 01:19:48 2014 +0200 56.3 @@ -1,8 +1,19 @@ 56.4 -slot.put("<br />") 56.5 +ui.title(_"Terms of use") 56.6 + 56.7 +ui.section( function() 56.8 + 56.9 + ui.sectionHead( function() 56.10 + ui.heading { level = 1, content = _"Terms of use" } 56.11 + end ) 56.12 + 56.13 + ui.sectionRow( function() 56.14 56.15 -ui.container{ 56.16 - attr = { class = "wiki use_terms" }, 56.17 - content = function() 56.18 - slot.put(format.wiki_text(config.use_terms)) 56.19 - end 56.20 -} 56.21 + ui.container{ 56.22 + attr = { class = "wiki use_terms" }, 56.23 + content = function() 56.24 + slot.put(config.use_terms) 56.25 + end 56.26 + } 56.27 + 56.28 + end ) 56.29 +end ) 56.30 \ No newline at end of file
57.1 --- a/app/main/initiative/_action/add_support.lua Thu Jul 10 01:02:43 2014 +0200 57.2 +++ b/app/main/initiative/_action/add_support.lua Thu Jul 10 01:19:48 2014 +0200 57.3 @@ -1,6 +1,8 @@ 57.4 local initiative = Initiative:new_selector():add_where{ "id = ?", param.get_id()}:single_object_mode():exec() 57.5 local auto_support = param.get("auto_support", atom.boolean) 57.6 57.7 +local draft_id = param.get("draft_id", atom.integer) 57.8 + 57.9 -- TODO important m1 selectors returning result _SET_! 57.10 local issue = initiative:get_reference_selector("issue"):for_share():single_object_mode():exec() 57.11 57.12 @@ -37,6 +39,13 @@ 57.13 :limit(1) 57.14 :single_object_mode() 57.15 :exec() 57.16 + 57.17 +if draft_id and draft_id ~= last_draft.id then 57.18 + slot.select("error", function() 57.19 + ui.tag{ content = _"The initiative draft has been updated again in the meanwhile, support not updated!" } 57.20 + end) 57.21 + return false 57.22 +end 57.23 57.24 if not supporter then 57.25 supporter = Supporter:new() 57.26 @@ -47,12 +56,11 @@ 57.27 supporter.auto_support = auto_support 57.28 end 57.29 supporter:save() 57.30 --- slot.put_into("notice", _"Your support has been added to this initiative") 57.31 elseif supporter.draft_id ~= last_draft.id then 57.32 supporter.draft_id = last_draft.id 57.33 supporter:save() 57.34 --- slot.put_into("notice", _"Your support has been updated to the latest draft") 57.35 + slot.put_into("notice", _"Your support has been updated to the latest draft") 57.36 else 57.37 --- slot.put_into("notice", _"You are already supporting the latest draft") 57.38 + slot.put_into("notice", _"You are already supporting the latest draft") 57.39 end 57.40
58.1 --- a/app/main/initiative/_action/create.lua Thu Jul 10 01:02:43 2014 +0200 58.2 +++ b/app/main/initiative/_action/create.lua Thu Jul 10 01:19:48 2014 +0200 58.3 @@ -73,23 +73,32 @@ 58.4 local name = util.trim(name) 58.5 58.6 if #name < 3 then 58.7 - slot.put_into("error", _"This name is really too short!") 58.8 + slot.put_into("error", _"Please enter a meaningful title for your initiative!") 58.9 + return false 58.10 +end 58.11 + 58.12 +if #name > 140 then 58.13 + slot.put_into("error", _"This title is too long!") 58.14 return false 58.15 end 58.16 58.17 -local formatting_engine = param.get("formatting_engine") 58.18 - 58.19 -local formatting_engine_valid = false 58.20 -for fe, dummy in pairs(config.formatting_engine_executeables) do 58.21 - if formatting_engine == fe then 58.22 - formatting_engine_valid = true 58.23 +local formatting_engine 58.24 +if config.enforce_formatting_engine then 58.25 + formatting_engine = config.enforce_formatting_engine 58.26 +else 58.27 + formatting_engine = param.get("formatting_engine") 58.28 + local formatting_engine_valid = false 58.29 + for i, fe in ipairs(config.formatting_engines) do 58.30 + if formatting_engine == fe.id then 58.31 + formatting_engine_valid = true 58.32 + end 58.33 + end 58.34 + if not formatting_engine_valid then 58.35 + error("invalid formatting engine!") 58.36 end 58.37 end 58.38 -if not formatting_engine_valid then 58.39 - error("invalid formatting engine!") 58.40 -end 58.41 58.42 -if param.get("preview") then 58.43 +if param.get("preview") or param.get("edit") then 58.44 return 58.45 end 58.46 58.47 @@ -155,7 +164,6 @@ 58.48 end 58.49 initiative.issue_id = issue.id 58.50 initiative.name = name 58.51 -param.update(initiative, "discussion_url") 58.52 initiative:save() 58.53 58.54 local draft = Draft:new()
59.1 --- a/app/main/initiative/_action/remove_support.lua Thu Jul 10 01:02:43 2014 +0200 59.2 +++ b/app/main/initiative/_action/remove_support.lua Thu Jul 10 01:19:48 2014 +0200 59.3 @@ -23,7 +23,5 @@ 59.4 59.5 if supporter then 59.6 supporter:destroy() 59.7 --- slot.put_into("notice", _"Your support has been removed from this initiative") 59.8 else 59.9 --- slot.put_into("notice", _"You are already not supporting this initiative") 59.10 end 59.11 \ No newline at end of file
60.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 60.2 +++ b/app/main/initiative/_bargraph.lua Thu Jul 10 01:19:48 2014 +0200 60.3 @@ -0,0 +1,61 @@ 60.4 +local initiative = param.get("initiative", "table") 60.5 +local batteled_initiative = param.get("battled_initiative", "table") 60.6 + 60.7 +local grey = "#eee" 60.8 + 60.9 +if initiative.issue.fully_frozen and initiative.issue.closed 60.10 + and initiative.negative_votes and initiative.positive_votes and initiative.rank ~= 1 then 60.11 + if not batteled_initiative then 60.12 + return 60.13 + end 60.14 + local battle1 = Battle:getByInitiativeIds(batteled_initiative.id, initiative.id) 60.15 + local battle2 = Battle:getByInitiativeIds(initiative.id, batteled_initiative.id) 60.16 + 60.17 + if not battle1 or not battle2 then 60.18 + return 60.19 + end 60.20 + 60.21 + local positive_votes = battle2.count 60.22 + local negative_votes = battle1.count 60.23 + 60.24 + local max_value = initiative.issue.voter_count 60.25 + if max_value > 0 then 60.26 + ui.bargraph{ 60.27 + max_value = max_value * 2, 60.28 + width = 100, 60.29 + bars = { 60.30 + { color = grey, value = max_value - negative_votes }, 60.31 + { color = "#a00", value = negative_votes }, 60.32 + { color = "#0a0", value = positive_votes }, 60.33 + { color = grey, value = max_value - positive_votes }, 60.34 + } 60.35 + } 60.36 + else 60.37 + ui.bargraph{ 60.38 + max_value = 1, 60.39 + width = 100, 60.40 + bars = { 60.41 + { color = grey, value = 1 }, 60.42 + } 60.43 + } 60.44 + end 60.45 +else 60.46 + local max_value = initiative.issue.population or 0 60.47 + local quorum 60.48 + if initiative.issue.accepted then 60.49 + quorum = initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den 60.50 + else 60.51 + quorum = initiative.issue.policy.issue_quorum_num / initiative.issue.policy.issue_quorum_den 60.52 + end 60.53 + ui.bargraph{ 60.54 + max_value = max_value, 60.55 + width = 100, 60.56 + quorum = max_value * quorum, 60.57 + quorum_color = "#00F", 60.58 + bars = { 60.59 + { color = "#5a5", value = (initiative.satisfied_supporter_count or 0) }, 60.60 + { color = "#fa5", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) }, 60.61 + { color = grey, value = max_value - (initiative.supporter_count or 0) }, 60.62 + } 60.63 + } 60.64 +end
61.1 --- a/app/main/initiative/_battles.lua Thu Jul 10 01:02:43 2014 +0200 61.2 +++ b/app/main/initiative/_battles.lua Thu Jul 10 01:19:48 2014 +0200 61.3 @@ -19,6 +19,7 @@ 61.4 :count() 61.5 61.6 if number_of_initiatives > 1 then 61.7 + ui.heading { level = 1, content = _"Preference comparison" } 61.8 ui.list{ 61.9 records = battled_initiatives, 61.10 columns = {
62.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 62.2 +++ b/app/main/initiative/_head.lua Thu Jul 10 01:19:48 2014 +0200 62.3 @@ -0,0 +1,198 @@ 62.4 +local initiative = param.get("initiative", "table") 62.5 +local member = param.get("member", "table") or app.session.member 62.6 + 62.7 +-- TODO performance 62.8 +local initiator 62.9 +if member then 62.10 + initiator = Initiator:by_pk(initiative.id, member.id) 62.11 +end 62.12 + 62.13 +local initiators_members_selector = initiative:get_reference_selector("initiating_members") 62.14 + :add_field("initiator.accepted", "accepted") 62.15 + :add_order_by("member.name") 62.16 +if initiator and initiator.accepted then 62.17 + initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted") 62.18 +else 62.19 + initiators_members_selector:add_where("initiator.accepted") 62.20 +end 62.21 + 62.22 +local initiators = initiators_members_selector:exec() 62.23 + 62.24 + 62.25 +ui.sectionHead( "initiativeInfo", function () 62.26 + 62.27 + ui.heading { 62.28 + level = 1, 62.29 + content = initiative.display_name 62.30 + } 62.31 + 62.32 + ui.container { attr = { class = "support" }, content = function () 62.33 + if initiative.supporter_count == nil then 62.34 + ui.tag { 62.35 + attr = { class = "supporterCount" }, 62.36 + content = _"[calculating]" 62.37 + } 62.38 + elseif initiative.issue.closed == nil then 62.39 + ui.tag { 62.40 + attr = { class = "satisfiedSupporterCount" }, 62.41 + content = _("#{count} supporter", { count = initiative.satisfied_supporter_count }) 62.42 + } 62.43 + if initiative.potential_supporter_count and 62.44 + initiative.potential_supporter_count > 0 62.45 + then 62.46 + slot.put ( " " ) 62.47 + ui.tag { 62.48 + attr = { class = "potentialSupporterCount" }, 62.49 + content = _("(+ #{count} potential)", { count = initiative.potential_supporter_count }) 62.50 + } 62.51 + end 62.52 + 62.53 + end 62.54 + 62.55 + slot.put ( "<br />" ) 62.56 + 62.57 + execute.view { 62.58 + module = "initiative", view = "_bargraph", params = { 62.59 + initiative = initiative 62.60 + } 62.61 + } 62.62 + end } 62.63 + 62.64 + if member then 62.65 + ui.container { attr = { class = "mySupport right" }, content = function () 62.66 + if initiative.issue.fully_frozen then 62.67 + if initiative.issue.member_info.direct_voted then 62.68 + --ui.image { attr = { class = "icon48 right" }, static = "icons/48/voted_ok.png" } 62.69 + ui.tag { content = _"You have voted" } 62.70 + slot.put("<br />") 62.71 + if not initiative.issue.closed then 62.72 + ui.link { 62.73 + module = "vote", view = "list", 62.74 + params = { issue_id = initiative.issue.id }, 62.75 + text = _"change vote" 62.76 + } 62.77 + else 62.78 + ui.link { 62.79 + module = "vote", view = "list", 62.80 + params = { issue_id = initiative.issue.id }, 62.81 + text = _"show vote" 62.82 + } 62.83 + end 62.84 + slot.put(" ") 62.85 + elseif active_trustee_id then 62.86 + ui.tag { content = _"You have voted via delegation" } 62.87 + ui.link { 62.88 + content = _"Show voting ballot", 62.89 + module = "vote", view = "list", params = { 62.90 + issue_id = initiative.issue.id, member_id = active_trustee_id 62.91 + } 62.92 + } 62.93 + elseif not initiative.issue.closed then 62.94 + ui.link { 62.95 + attr = { class = "btn btn-default" }, 62.96 + module = "vote", view = "list", 62.97 + params = { issue_id = initiative.issue.id }, 62.98 + text = _"vote now" 62.99 + } 62.100 + end 62.101 + elseif initiative.member_info.supported then 62.102 + if initiative.member_info.satisfied then 62.103 + ui.image { attr = { class = "icon48 right" }, static = "icons/32/support_satisfied.png" } 62.104 + else 62.105 + ui.image { attr = { class = "icon48 right" }, static = "icons/32/support_unsatisfied.png" } 62.106 + end 62.107 + ui.container { content = _"You are supporter" } 62.108 + 62.109 + if initiative.issue.member_info.own_participation then 62.110 + ui.link { 62.111 + attr = { class = "btn-link" }, 62.112 + module = "initiative", action = "remove_support", 62.113 + routing = { default = { 62.114 + mode = "redirect", module = "initiative", view = "show", id = initiative.id 62.115 + } }, 62.116 + id = initiative.id, 62.117 + text = "remove my support" 62.118 + } 62.119 + 62.120 + else 62.121 + 62.122 + ui.link { 62.123 + module = "delegation", view = "show", params = { 62.124 + issue_id = initiative.issue_id, 62.125 + initiative_id = initiative.id 62.126 + }, 62.127 + content = _"via delegation" 62.128 + } 62.129 + 62.130 + end 62.131 + 62.132 + slot.put(" ") 62.133 + 62.134 + 62.135 + else 62.136 + ui.link { 62.137 + attr = { class = "btn btn-default" }, 62.138 + module = "initiative", action = "add_support", 62.139 + routing = { default = { 62.140 + mode = "redirect", module = "initiative", view = "show", id = initiative.id 62.141 + } }, 62.142 + id = initiative.id, 62.143 + text = _"add my support" 62.144 + } 62.145 + 62.146 + end 62.147 + end } 62.148 + 62.149 + end 62.150 + 62.151 + slot.put("<br style='clear: both;'/>") 62.152 + 62.153 + ui.container { 62.154 + attr = { class = "initiators" }, 62.155 + content = function () 62.156 + 62.157 + if app.session:has_access("authors_pseudonymous") then 62.158 + for i, member in ipairs(initiators) do 62.159 + if i > 1 then 62.160 + slot.put(" ") 62.161 + end 62.162 + util.micro_avatar(member) 62.163 + if member.accepted == nil then 62.164 + slot.put ( " " ) 62.165 + ui.tag { content = _"(invited)" } 62.166 + end 62.167 + end -- for i, member 62.168 + 62.169 + end 62.170 + 62.171 + end 62.172 + } -- ui.container "initiators" 62.173 + 62.174 + ui.container { 62.175 + attr = { class = "links" }, 62.176 + content = function () 62.177 + 62.178 + local drafts_count = initiative:get_reference_selector("drafts"):count() 62.179 + ui.link { 62.180 + content = _("suggestions (#{count}) ↓", { 62.181 + count = # ( initiative.suggestions ) 62.182 + }), 62.183 + external = "#suggestions" 62.184 + } 62.185 + 62.186 + slot.put ( " | " ) 62.187 + 62.188 + ui.link{ 62.189 + module = "initiative", view = "history", id = initiative.id, 62.190 + content = _("draft history (#{count})", { count = drafts_count }) 62.191 + } 62.192 + 62.193 + end 62.194 + } -- ui.containers "links" 62.195 + end ) 62.196 + 62.197 + execute.view { 62.198 + module = "initiative", view = "_sidebar_state", 62.199 + params = { initiative = initiative } 62.200 + } 62.201 +
63.1 --- a/app/main/initiative/_initiators.lua Thu Jul 10 01:02:43 2014 +0200 63.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 63.3 @@ -1,58 +0,0 @@ 63.4 -local initiative = param.get("initiative", "table") 63.5 -local initiator = param.get("initiator", "table") 63.6 -local initiators_members_selector = param.get("initiators_members_selector", "table") 63.7 - 63.8 -local initiator_count = initiators_members_selector:count() 63.9 - 63.10 -if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 63.11 - ui.link{ 63.12 - attr = { class = "action" }, 63.13 - content = function() 63.14 - ui.image{ static = "icons/16/user_add.png" } 63.15 - slot.put(_"Invite initiator") 63.16 - end, 63.17 - module = "initiative", 63.18 - view = "add_initiator", 63.19 - params = { initiative_id = initiative.id } 63.20 - } 63.21 - if initiator_count > 1 then 63.22 - ui.link{ 63.23 - content = function() 63.24 - ui.image{ static = "icons/16/user_delete.png" } 63.25 - slot.put(_"Remove initiator") 63.26 - end, 63.27 - module = "initiative", 63.28 - view = "remove_initiator", 63.29 - params = { initiative_id = initiative.id } 63.30 - } 63.31 - end 63.32 -end 63.33 -if initiator and initiator.accepted == false then 63.34 - ui.link{ 63.35 - image = { static = "icons/16/user_delete.png" }, 63.36 - text = _"Cancel refuse of invitation", 63.37 - module = "initiative", 63.38 - action = "remove_initiator", 63.39 - params = { 63.40 - initiative_id = initiative.id, 63.41 - member_id = app.session.member.id 63.42 - }, 63.43 - routing = { 63.44 - ok = { 63.45 - mode = "redirect", 63.46 - module = "initiative", 63.47 - view = "show", 63.48 - id = initiative.id 63.49 - } 63.50 - } 63.51 - } 63.52 -end 63.53 - 63.54 -execute.view{ 63.55 - module = "member", 63.56 - view = "_list", 63.57 - params = { 63.58 - members_selector = initiators_members_selector, 63.59 - initiator = initiator 63.60 - } 63.61 -}
64.1 --- a/app/main/initiative/_list.lua Thu Jul 10 01:02:43 2014 +0200 64.2 +++ b/app/main/initiative/_list.lua Thu Jul 10 01:19:48 2014 +0200 64.3 @@ -1,79 +1,79 @@ 64.4 -local issue = param.get("issue", "table") 64.5 -local initiatives_selector = param.get("initiatives_selector", "table") 64.6 +local member = param.get("member", "table") or app.session.member 64.7 64.8 -local initiatives 64.9 -if issue then 64.10 - initiatives = issue.initiatives 64.11 -else 64.12 - initiatives = initiatives_selector:exec() 64.13 - initiatives:load_everything_for_member_id(app.session.member_id) 64.14 -end 64.15 - 64.16 -local highlight_initiative = param.get("highlight_initiative", "table") 64.17 - 64.18 -local for_member = param.get("for_member", "table") or app.session.member 64.19 +local initiatives = param.get("initiatives", "table") 64.20 +local highlight_initiative_id = param.get ( "highlight_initiative_id", "number" ) 64.21 64.22 -local limit = param.get("limit", atom.number) 64.23 -local hide_more_initiatives = param.get("hide_more_initiatives", atom.boolean) 64.24 +local for_initiative = param.get("initiative", "table") 64.25 64.26 -local more_initiatives_count 64.27 -if limit then 64.28 - if #initiatives > limit then 64.29 - more_initiatives_count = #initiatives - limit 64.30 - end 64.31 - initiatives = {} 64.32 - for i, initiative in ipairs(issue.initiatives) do 64.33 - if i <= limit then 64.34 - initiatives[#initiatives+1] = initiative 64.35 - end 64.36 - end 64.37 -end 64.38 +local for_event = param.get("for_event", atom.boolean) 64.39 64.40 -local name = "initiative_list" 64.41 -if issue then 64.42 - name = "issue_" .. tostring(issue.id) .. "_initiative_list" 64.43 +if for_initiative then 64.44 + initiatives = { for_initiative } 64.45 end 64.46 64.47 -ui.add_partial_param_names{ name } 64.48 +ui.tag { 64.49 + tag = "ul", 64.50 + attr = { class = "initiatives" }, 64.51 + content = function () 64.52 + local last_group 64.53 + for i, initiative in ipairs(initiatives) do 64.54 + local group 64.55 + if initiative.issue.closed then 64.56 + if initiative.rank == 1 then 64.57 + group = "1st_rank" 64.58 + elseif initiative.admitted then 64.59 + group = "admitted" 64.60 + elseif initiative.revoked_by_member_id then 64.61 + group = "revoked" 64.62 + else 64.63 + group = "not_admitted" 64.64 + end 64.65 + end 64.66 + if not for_initiative and group ~= last_group and not for_event then 64.67 64.68 -if highlight_initiative then 64.69 - local highlight_initiative_found 64.70 - for i, initiative in ipairs(initiatives) do 64.71 - if initiative.id == highlight_initiative.id then 64.72 - highhighlight_initiative_found = true 64.73 - end 64.74 - end 64.75 - if not highhighlight_initiative_found then 64.76 - initiatives[#initiatives+1] = highlight_initiative 64.77 - if more_initiatives_count then 64.78 - more_initiatives_count = more_initiatives_count - 1 64.79 + local text 64.80 + if group == "admitted" then 64.81 + if initiative.issue.state == "finished_with_winner" then 64.82 + text = _"Competing initiatives in pairwise comparison to winner:" 64.83 + else 64.84 + text = _"Competing initiatives in pairwise comparison to best initiative:" 64.85 + end 64.86 + end 64.87 + if group == "not_admitted" then 64.88 + text = _("Competing initiatives failed the 2nd quorum (#{num}/#{den}):", { 64.89 + num = initiative.issue.policy.initiative_quorum_num, 64.90 + den = initiative.issue.policy.initiative_quorum_den 64.91 + } ) 64.92 + end 64.93 + if text then 64.94 + slot.put("<br />") 64.95 + ui.container { attr = { class = "result" }, content = text } 64.96 + end 64.97 + last_group = group 64.98 + end 64.99 + 64.100 + local class = "" 64.101 + if highlight_initiative_id == initiative.id then 64.102 + class = "highlighted" 64.103 + end 64.104 + if app.session.member then 64.105 + if initiative.member_info.supported then 64.106 + class = class .. " supported" 64.107 + end 64.108 + if initiative.member_info.satisfied then 64.109 + class = class .. " satisfied" 64.110 + end 64.111 + end 64.112 + ui.tag { 64.113 + tag = "li", attr = { class = class }, 64.114 + content = function () 64.115 + execute.view { 64.116 + module = "initiative", view = "_list_element", params = { 64.117 + initiative = initiative, for_event = for_event 64.118 + } 64.119 + } 64.120 + end 64.121 + } 64.122 end 64.123 - end 64.124 -end 64.125 -for i, initiative in ipairs(initiatives) do 64.126 - execute.view{ 64.127 - module = "initiative", 64.128 - view = "_list_element", 64.129 - params = { 64.130 - initiative = initiative, 64.131 - selected = highlight_initiative and highlight_initiative.id == initiative.id or nil, 64.132 - for_member = for_member 64.133 - } 64.134 - } 64.135 -end 64.136 - 64.137 -if not hide_more_initiatives and more_initiatives_count and more_initiatives_count > 0 then 64.138 - local text 64.139 - if more_initiatives_count == 1 then 64.140 - text = _("and one more initiative") 64.141 - else 64.142 - text = _("and #{count} more initiatives", { count = more_initiatives_count }) 64.143 - end 64.144 - ui.link{ 64.145 - attr = { class = "more_initiatives_link" }, 64.146 - content = text, 64.147 - module = "issue", 64.148 - view = "show", 64.149 - id = issue.id, 64.150 - } 64.151 -end 64.152 + end 64.153 +} 64.154 \ No newline at end of file
65.1 --- a/app/main/initiative/_list_element.lua Thu Jul 10 01:02:43 2014 +0200 65.2 +++ b/app/main/initiative/_list_element.lua Thu Jul 10 01:19:48 2014 +0200 65.3 @@ -1,152 +1,110 @@ 65.4 local initiative = param.get("initiative", "table") 65.5 -local selected = param.get("selected", atom.boolean) 65.6 -local for_member = param.get("for_member", "table") or app.session.member 65.7 +local for_event = param.get("for_event", atom.boolean) 65.8 + 65.9 +local issue = initiative.issue 65.10 65.11 local class = "initiative" 65.12 65.13 -if selected then 65.14 - class = class .. " selected" 65.15 +if initiative.rank == 1 then 65.16 + class = class .. " rank1" 65.17 end 65.18 65.19 -if initiative.polling then 65.20 - class = class .. " polling" 65.21 +if initiative.revoked then 65.22 + class = class .. " revoked" 65.23 end 65.24 65.25 -ui.container{ attr = { class = class }, content = function() 65.26 - 65.27 - ui.container{ attr = { class = "rank" }, content = function() 65.28 - if initiative.issue.fully_frozen and initiative.issue.closed 65.29 - or initiative.admitted == false 65.30 - then 65.31 - ui.field.rank{ attr = { class = "rank" }, value = initiative.rank, eligible = initiative.eligible } 65.32 - elseif not initiative.issue.closed then 65.33 - ui.image{ static = "icons/16/script.png" } 65.34 - else 65.35 - ui.image{ static = "icons/16/cross.png" } 65.36 - end 65.37 - end } 65.38 - 65.39 - ui.container{ attr = { class = "bar" }, content = function() 65.40 - if initiative.issue.fully_frozen and initiative.issue.closed then 65.41 - if initiative.negative_votes and initiative.positive_votes then 65.42 - local max_value = initiative.issue.voter_count 65.43 - ui.bargraph{ 65.44 - max_value = max_value, 65.45 - width = 100, 65.46 - bars = { 65.47 - { color = "#0a5", value = initiative.positive_votes }, 65.48 - { color = "#aaa", value = max_value - initiative.negative_votes - initiative.positive_votes }, 65.49 - { color = "#a00", value = initiative.negative_votes }, 65.50 - } 65.51 - } 65.52 - else 65.53 - slot.put(" ") 65.54 - end 65.55 - else 65.56 - local max_value = initiative.issue.population or 0 65.57 - local quorum 65.58 - if initiative.issue.accepted then 65.59 - quorum = initiative.issue.policy.initiative_quorum_num / initiative.issue.policy.initiative_quorum_den 65.60 - else 65.61 - quorum = initiative.issue.policy.issue_quorum_num / initiative.issue.policy.issue_quorum_den 65.62 - end 65.63 - ui.bargraph{ 65.64 - max_value = max_value, 65.65 - width = 100, 65.66 - quorum = max_value * quorum, 65.67 - quorum_color = "#00F", 65.68 - bars = { 65.69 - { color = "#0a5", value = (initiative.satisfied_supporter_count or 0) }, 65.70 - { color = "#aaa", value = (initiative.supporter_count or 0) - (initiative.satisfied_supporter_count or 0) }, 65.71 - { color = "#fff", value = max_value - (initiative.supporter_count or 0) }, 65.72 +ui.container{ 65.73 + attr = { class = class }, 65.74 + content = function () 65.75 + if initiative.rank ~= 1 and not for_event then 65.76 + execute.view { 65.77 + module = "initiative", view = "_bargraph", params = { 65.78 + initiative = initiative, 65.79 + battled_initiative = issue.initiatives[1] 65.80 } 65.81 } 65.82 + slot.put(" ") 65.83 end 65.84 - end } 65.85 - 65.86 - if app.session.member_id then 65.87 - ui.container{ attr = { class = "interest" }, content = function() 65.88 - if initiative.member_info.initiated then 65.89 - local label 65.90 - if for_member and for_member.id ~= app.session.member_id then 65.91 - label = _"This member is initiator of this initiative" 65.92 - else 65.93 - label = _"You are initiator of this initiative" 65.94 - end 65.95 - ui.image{ 65.96 - attr = { alt = label, title = label }, 65.97 - static = "icons/16/user_edit.png" 65.98 + ui.tag { 65.99 + attr = { class = "initiative_name" }, 65.100 + content = function() 65.101 + ui.link { 65.102 + text = initiative.display_name, 65.103 + module = "initiative", view = "show", id = initiative.id 65.104 } 65.105 - elseif initiative.member_info.directly_supported then 65.106 - if initiative.member_info.satisfied then 65.107 - if for_member and for_member.id ~= app.session.member_id then 65.108 - label = _"This member is supporter of this initiative" 65.109 - else 65.110 - local label = _"You are supporter of this initiative" 65.111 + slot.put(" ") 65.112 + if initiative.vote_grade ~= nil then 65.113 + if initiative.vote_grade > 0 then 65.114 + local text = _"voted yes" 65.115 + ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_satisfied.png" } 65.116 + elseif initiative.vote_grade == 0 then 65.117 + elseif initiative.vote_grade < 0 then 65.118 + local text = _"voted no" 65.119 + ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/voted_no.png" } 65.120 end 65.121 - ui.image{ 65.122 - attr = { alt = label, title = label }, 65.123 - static = "icons/16/thumb_up_green.png" 65.124 - } 65.125 - else 65.126 - if for_member and for_member.id ~= app.session.member_id then 65.127 - label = _"This member is potential supporter of this initiative" 65.128 - else 65.129 - local label = _"You are potential supporter of this initiative" 65.130 + elseif app.session.member then 65.131 + if initiative.member_info.supported then 65.132 + if initiative.member_info.satisfied then 65.133 + local text = _"supporter" 65.134 + ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_satisfied.png" } 65.135 + else 65.136 + local text = _"supporter with restricting suggestions" 65.137 + ui.image { attr = { class = "icon16", title = text, alt = text }, static = "icons/32/support_unsatisfied.png" } 65.138 + end 65.139 end 65.140 - ui.image{ 65.141 - attr = { alt = label, title = label }, 65.142 - static = "icons/16/thumb_up.png" 65.143 - } 65.144 - end 65.145 - elseif initiative.member_info.supported then 65.146 - if initiative.member_info.satisfied then 65.147 - if for_member and for_member.id ~= app.session.member_id then 65.148 - label = _"This member is supporter of this initiative via delegation" 65.149 - else 65.150 - local label = _"You are supporter of this initiative via delegation" 65.151 - end 65.152 - ui.image{ 65.153 - attr = { alt = label, title = label }, 65.154 - static = "icons/16/thumb_up_green_arrow.png" 65.155 - } 65.156 - else 65.157 - if for_member and for_member.id ~= app.session.member_id then 65.158 - label = _"This member is potential supporter of this initiative via delegation" 65.159 - else 65.160 - local label = _"You are potential supporter of this initiative via delegation" 65.161 - end 65.162 - ui.image{ 65.163 - attr = { alt = label, title = label }, 65.164 - static = "icons/16/thumb_up_arrow.png" 65.165 - } 65.166 end 65.167 end 65.168 - end } 65.169 + } 65.170 + 65.171 end 65.172 - 65.173 - ui.container{ attr = { class = "name" }, content = function() 65.174 - local link_class = "initiative_link" 65.175 - if initiative.revoked then 65.176 - link_class = "revoked" 65.177 +} 65.178 + 65.179 +if initiative.rank == 1 65.180 + and issue.voter_count 65.181 + and initiative.positive_votes ~= nil 65.182 + and initiative.negative_votes ~= nil 65.183 + and not for_event 65.184 +then 65.185 + function percent(p, q) 65.186 + if q > 0 then 65.187 + return math.floor(p / q * 100) .. "%" 65.188 + else 65.189 + return "0%" 65.190 end 65.191 - ui.link{ 65.192 - attr = { class = link_class }, 65.193 - content = function() 65.194 - local name 65.195 - if initiative.name_highlighted then 65.196 - name = encode.highlight(initiative.name_highlighted) 65.197 - else 65.198 - name = encode.html(initiative.shortened_name) 65.199 - end 65.200 - ui.tag{ content = "i" .. initiative.id .. ": " } 65.201 - slot.put(name) 65.202 - end, 65.203 - module = "initiative", 65.204 - view = "show", 65.205 - id = initiative.id 65.206 - } 65.207 - 65.208 - end } 65.209 + end 65.210 + local result = "" 65.211 + if initiative.eligible then 65.212 + result = _("Reached #{sign}#{num}/#{den}", { 65.213 + sign = issue.policy.direct_majority_strict and ">" or "≥", 65.214 + num = issue.policy.direct_majority_num, 65.215 + den = issue.policy.direct_majority_den 65.216 + }) 65.217 + else 65.218 + result = _("Failed #{sign}#{num}/#{den}", { 65.219 + sign = issue.policy.direct_majority_strict and ">" or "≥", 65.220 + num = issue.policy.direct_majority_num, 65.221 + den = issue.policy.direct_majority_den 65.222 + }) 65.223 + end 65.224 + local neutral_count = issue.voter_count - initiative.positive_votes - initiative.negative_votes 65.225 + 65.226 + local result_text 65.227 + 65.228 + if issue.voter_count > 0 then 65.229 + result_text = _("#{result}: #{yes_count} Yes (#{yes_percent}), #{no_count} No (#{no_percent}), #{neutral_count} Abstention (#{neutral_percent})", { 65.230 + result = result, 65.231 + yes_count = initiative.positive_votes, 65.232 + yes_percent = percent(initiative.positive_votes, issue.voter_count), 65.233 + neutral_count = neutral_count, 65.234 + neutral_percent = percent(neutral_count, issue.voter_count), 65.235 + no_count = initiative.negative_votes, 65.236 + no_percent = percent(initiative.negative_votes, issue.voter_count) 65.237 + }) 65.238 + else 65.239 + result_text = _("#{result}: No votes (0)", { result = result }) 65.240 + end 65.241 + 65.242 + ui.container { attr = { class = "result" }, content = result_text } 65.243 65.244 -end } 65.245 +end 65.246 +
66.1 --- a/app/main/initiative/_show.lua Thu Jul 10 01:02:43 2014 +0200 66.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 66.3 @@ -1,531 +0,0 @@ 66.4 -local initiative = param.get("initiative", "table") 66.5 - 66.6 -local show_as_head = param.get("show_as_head", atom.boolean) 66.7 - 66.8 -initiative:load_everything_for_member_id(app.session.member_id) 66.9 - 66.10 -local issue = initiative.issue 66.11 - 66.12 --- TODO performance 66.13 -local initiator 66.14 -if app.session.member_id then 66.15 - initiator = Initiator:by_pk(initiative.id, app.session.member.id) 66.16 -end 66.17 - 66.18 -if app.session.member_id then 66.19 - issue:load_everything_for_member_id(app.session.member_id) 66.20 -end 66.21 - 66.22 -app.html_title.title = initiative.name 66.23 -app.html_title.subtitle = _("Initiative ##{id}", { id = initiative.id }) 66.24 - 66.25 -slot.select("head", function() 66.26 - execute.view{ 66.27 - module = "issue", view = "_head", 66.28 - params = { issue = issue, initiative = initiative } 66.29 - } 66.30 -end) 66.31 - 66.32 -local initiators_members_selector = initiative:get_reference_selector("initiating_members") 66.33 - :add_field("initiator.accepted", "accepted") 66.34 - :add_order_by("member.name") 66.35 -if initiator and initiator.accepted then 66.36 - initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted") 66.37 -else 66.38 - initiators_members_selector:add_where("initiator.accepted") 66.39 -end 66.40 - 66.41 -local initiators = initiators_members_selector:exec() 66.42 - 66.43 - 66.44 -local initiatives_selector = initiative.issue:get_reference_selector("initiatives") 66.45 -slot.select("head", function() 66.46 - execute.view{ 66.47 - module = "issue", 66.48 - view = "_show", 66.49 - params = { 66.50 - issue = initiative.issue, 66.51 - initiative_limit = 3, 66.52 - for_initiative = initiative 66.53 - } 66.54 - } 66.55 -end) 66.56 - 66.57 -util.help("initiative.show") 66.58 - 66.59 -local class = "initiative_head" 66.60 - 66.61 -if initiative.polling then 66.62 - class = class .. " polling" 66.63 -end 66.64 - 66.65 -ui.container{ attr = { class = class }, content = function() 66.66 - 66.67 - local text = _("Initiative i#{id}: #{name}", { id = initiative.id, name = initiative.name }) 66.68 - if show_as_head then 66.69 - ui.link{ 66.70 - attr = { class = "title" }, text = text, 66.71 - module = "initiative", view = "show", id = initiative.id 66.72 - } 66.73 - else 66.74 - ui.container{ attr = { class = "title" }, content = text } 66.75 - end 66.76 - if app.session:has_access("authors_pseudonymous") then 66.77 - ui.container{ attr = { class = "content" }, content = function() 66.78 - ui.tag{ 66.79 - attr = { class = "initiator_names" }, 66.80 - content = function() 66.81 - for i, initiator in ipairs(initiators) do 66.82 - slot.put(" ") 66.83 - if app.session:has_access("all_pseudonymous") then 66.84 - ui.link{ 66.85 - content = function () 66.86 - execute.view{ 66.87 - module = "member_image", 66.88 - view = "_show", 66.89 - params = { 66.90 - member = initiator, 66.91 - image_type = "avatar", 66.92 - show_dummy = true, 66.93 - class = "micro_avatar", 66.94 - popup_text = text 66.95 - } 66.96 - } 66.97 - end, 66.98 - module = "member", view = "show", id = initiator.id 66.99 - } 66.100 - slot.put(" ") 66.101 - end 66.102 - ui.link{ 66.103 - text = initiator.name, 66.104 - module = "member", view = "show", id = initiator.id 66.105 - } 66.106 - if not initiator.accepted then 66.107 - ui.tag{ attr = { title = _"Not accepted yet" }, content = "?" } 66.108 - end 66.109 - end 66.110 - if initiator and initiator.accepted and not initiative.issue.fully_frozen and not initiative.issue.closed and not initiative.revoked then 66.111 - slot.put(" · ") 66.112 - ui.link{ 66.113 - attr = { class = "action" }, 66.114 - content = function() 66.115 - slot.put(_"Invite initiator") 66.116 - end, 66.117 - module = "initiative", 66.118 - view = "add_initiator", 66.119 - params = { initiative_id = initiative.id } 66.120 - } 66.121 - if #initiators > 1 then 66.122 - slot.put(" · ") 66.123 - ui.link{ 66.124 - content = function() 66.125 - slot.put(_"Remove initiator") 66.126 - end, 66.127 - module = "initiative", 66.128 - view = "remove_initiator", 66.129 - params = { initiative_id = initiative.id } 66.130 - } 66.131 - end 66.132 - end 66.133 - if initiator and initiator.accepted == false then 66.134 - slot.put(" · ") 66.135 - ui.link{ 66.136 - text = _"Cancel refuse of invitation", 66.137 - module = "initiative", 66.138 - action = "remove_initiator", 66.139 - params = { 66.140 - initiative_id = initiative.id, 66.141 - member_id = app.session.member.id 66.142 - }, 66.143 - routing = { 66.144 - ok = { 66.145 - mode = "redirect", 66.146 - module = "initiative", 66.147 - view = "show", 66.148 - id = initiative.id 66.149 - } 66.150 - } 66.151 - } 66.152 - end 66.153 - if (initiative.discussion_url and #initiative.discussion_url > 0) then 66.154 - slot.put(" · ") 66.155 - if initiative.discussion_url:find("^https?://") then 66.156 - if initiative.discussion_url and #initiative.discussion_url > 0 then 66.157 - ui.link{ 66.158 - attr = { 66.159 - target = "_blank", 66.160 - title = _"Discussion with initiators" 66.161 - }, 66.162 - text = _"Discuss with initiators", 66.163 - external = initiative.discussion_url 66.164 - } 66.165 - end 66.166 - else 66.167 - slot.put(encode.html(initiative.discussion_url)) 66.168 - end 66.169 - end 66.170 - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 66.171 - slot.put(" · ") 66.172 - ui.link{ 66.173 - text = _"change discussion URL", 66.174 - module = "initiative", 66.175 - view = "edit", 66.176 - id = initiative.id 66.177 - } 66.178 - slot.put(" ") 66.179 - end 66.180 - end 66.181 - } 66.182 - end } 66.183 - end 66.184 - 66.185 - if app.session.member_id then 66.186 - ui.container{ attr = { class = "content" }, content = function() 66.187 - execute.view{ 66.188 - module = "supporter", 66.189 - view = "_show_box", 66.190 - params = { 66.191 - initiative = initiative 66.192 - } 66.193 - } 66.194 - end } 66.195 - end 66.196 - 66.197 - 66.198 - -- voting results 66.199 - if initiative.issue.fully_frozen and initiative.issue.closed and initiative.admitted then 66.200 - local class = initiative.winner and "admitted_info" or "not_admitted_info" 66.201 - ui.container{ 66.202 - attr = { class = class }, 66.203 - content = function() 66.204 - local max_value = initiative.issue.voter_count 66.205 - slot.put(" ") 66.206 - local positive_votes = initiative.positive_votes 66.207 - local negative_votes = initiative.negative_votes 66.208 - local sum_votes = initiative.positive_votes + initiative.negative_votes 66.209 - local function perc(votes, sum) 66.210 - if sum > 0 and votes > 0 then return " (" .. string.format( "%.f", votes * 100 / sum ) .. "%)" end 66.211 - return "" 66.212 - end 66.213 - slot.put(_"Yes" .. ": <b>" .. tostring(positive_votes) .. perc(positive_votes, sum_votes) .. "</b>") 66.214 - slot.put(" · ") 66.215 - slot.put(_"Abstention" .. ": <b>" .. tostring(max_value - initiative.negative_votes - initiative.positive_votes) .. "</b>") 66.216 - slot.put(" · ") 66.217 - slot.put(_"No" .. ": <b>" .. tostring(initiative.negative_votes) .. perc(negative_votes, sum_votes) .. "</b>") 66.218 - slot.put(" · ") 66.219 - slot.put("<b>") 66.220 - if initiative.winner then 66.221 - slot.put(_"Approved") 66.222 - elseif initiative.rank then 66.223 - slot.put(_("Not approved (rank #{rank})", { rank = initiative.rank })) 66.224 - else 66.225 - slot.put(_"Not approved") 66.226 - end 66.227 - slot.put("</b>") 66.228 - end 66.229 - } 66.230 - end 66.231 - 66.232 - ui.container{ attr = { class = "content" }, content = function() 66.233 - execute.view{ 66.234 - module = "initiative", 66.235 - view = "_battles", 66.236 - params = { initiative = initiative } 66.237 - } 66.238 - end } 66.239 - 66.240 - -- initiative not admitted info 66.241 - if initiative.admitted == false then 66.242 - local policy = initiative.issue.policy 66.243 - ui.container{ 66.244 - attr = { class = "not_admitted_info" }, 66.245 - content = _("This initiative has not been admitted! It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) }) 66.246 - } 66.247 - end 66.248 - 66.249 - -- initiative revoked info 66.250 - if initiative.revoked then 66.251 - ui.container{ 66.252 - attr = { class = "revoked_info" }, 66.253 - content = function() 66.254 - slot.put(_("This initiative has been revoked at #{revoked}", { revoked = format.timestamp(initiative.revoked) })) 66.255 - local suggested_initiative = initiative.suggested_initiative 66.256 - if suggested_initiative then 66.257 - slot.put("<br /><br />") 66.258 - slot.put(_("The initiators suggest to support the following initiative:")) 66.259 - slot.put(" ") 66.260 - ui.link{ 66.261 - content = _("Issue ##{id}", { id = suggested_initiative.issue.id } ) .. ": " .. encode.html(suggested_initiative.name), 66.262 - module = "initiative", 66.263 - view = "show", 66.264 - id = suggested_initiative.id 66.265 - } 66.266 - end 66.267 - end 66.268 - } 66.269 - end 66.270 - 66.271 - 66.272 - -- invited as initiator 66.273 - if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then 66.274 - ui.container{ 66.275 - attr = { class = "initiator_invite_info" }, 66.276 - content = function() 66.277 - slot.put(_"You are invited to become initiator of this initiative.") 66.278 - slot.put(" ") 66.279 - ui.link{ 66.280 - image = { static = "icons/16/tick.png" }, 66.281 - text = _"Accept invitation", 66.282 - module = "initiative", 66.283 - action = "accept_invitation", 66.284 - id = initiative.id, 66.285 - routing = { 66.286 - default = { 66.287 - mode = "redirect", 66.288 - module = request.get_module(), 66.289 - view = request.get_view(), 66.290 - id = param.get_id_cgi(), 66.291 - params = param.get_all_cgi() 66.292 - } 66.293 - } 66.294 - } 66.295 - slot.put(" ") 66.296 - ui.link{ 66.297 - image = { static = "icons/16/cross.png" }, 66.298 - text = _"Refuse invitation", 66.299 - module = "initiative", 66.300 - action = "reject_initiator_invitation", 66.301 - params = { 66.302 - initiative_id = initiative.id, 66.303 - member_id = app.session.member.id 66.304 - }, 66.305 - routing = { 66.306 - default = { 66.307 - mode = "redirect", 66.308 - module = request.get_module(), 66.309 - view = request.get_view(), 66.310 - id = param.get_id_cgi(), 66.311 - params = param.get_all_cgi() 66.312 - } 66.313 - } 66.314 - } 66.315 - end 66.316 - } 66.317 - end 66.318 - 66.319 - -- draft updated 66.320 - local supporter 66.321 - 66.322 - if app.session.member_id then 66.323 - supporter = app.session.member:get_reference_selector("supporters") 66.324 - :add_where{ "initiative_id = ?", initiative.id } 66.325 - :optional_object_mode() 66.326 - :exec() 66.327 - end 66.328 - 66.329 - if supporter and not initiative.issue.closed then 66.330 - local old_draft_id = supporter.draft_id 66.331 - local new_draft_id = initiative.current_draft.id 66.332 - if old_draft_id ~= new_draft_id then 66.333 - ui.container{ 66.334 - attr = { class = "draft_updated_info" }, 66.335 - content = function() 66.336 - slot.put(_"The draft of this initiative has been updated!") 66.337 - slot.put(" ") 66.338 - ui.link{ 66.339 - content = _"Show diff", 66.340 - module = "draft", 66.341 - view = "diff", 66.342 - params = { 66.343 - old_draft_id = old_draft_id, 66.344 - new_draft_id = new_draft_id 66.345 - } 66.346 - } 66.347 - if not initiative.revoked then 66.348 - slot.put(" ") 66.349 - ui.link{ 66.350 - text = _"Refresh support to current draft", 66.351 - module = "initiative", 66.352 - action = "add_support", 66.353 - id = initiative.id, 66.354 - routing = { 66.355 - default = { 66.356 - mode = "redirect", 66.357 - module = "initiative", 66.358 - view = "show", 66.359 - id = initiative.id 66.360 - } 66.361 - } 66.362 - } 66.363 - end 66.364 - end 66.365 - } 66.366 - end 66.367 - end 66.368 - 66.369 - if not show_as_head then 66.370 - local drafts_count = initiative:get_reference_selector("drafts"):count() 66.371 - 66.372 - ui.container{ attr = { class = "content" }, content = function() 66.373 - 66.374 - if initiator and initiator.accepted and not initiative.issue.half_frozen and not initiative.issue.closed and not initiative.revoked then 66.375 - ui.link{ 66.376 - content = function() 66.377 - slot.put(_"Edit draft") 66.378 - end, 66.379 - module = "draft", 66.380 - view = "new", 66.381 - params = { initiative_id = initiative.id } 66.382 - } 66.383 - slot.put(" · ") 66.384 - ui.link{ 66.385 - content = function() 66.386 - slot.put(_"Revoke initiative") 66.387 - end, 66.388 - module = "initiative", 66.389 - view = "revoke", 66.390 - id = initiative.id 66.391 - } 66.392 - slot.put(" · ") 66.393 - end 66.394 - 66.395 - ui.tag{ 66.396 - attr = { class = "draft_version" }, 66.397 - content = _("Latest draft created at #{date} #{time}", { 66.398 - date = format.date(initiative.current_draft.created), 66.399 - time = format.time(initiative.current_draft.created) 66.400 - }) 66.401 - } 66.402 - if drafts_count > 1 then 66.403 - slot.put(" · ") 66.404 - ui.link{ 66.405 - module = "draft", view = "list", params = { initiative_id = initiative.id }, 66.406 - text = _("List all revisions (#{count})", { count = drafts_count }) 66.407 - } 66.408 - end 66.409 - end } 66.410 - 66.411 - execute.view{ 66.412 - module = "draft", 66.413 - view = "_show", 66.414 - params = { 66.415 - draft = initiative.current_draft 66.416 - } 66.417 - } 66.418 - end 66.419 -end } 66.420 - 66.421 -if not show_as_head then 66.422 - execute.view{ 66.423 - module = "suggestion", 66.424 - view = "_list", 66.425 - params = { 66.426 - initiative = initiative, 66.427 - suggestions_selector = initiative:get_reference_selector("suggestions"), 66.428 - tab_id = param.get("tab_id") 66.429 - } 66.430 - } 66.431 - 66.432 - 66.433 - if app.session:has_access("all_pseudonymous") then 66.434 - if initiative.issue.fully_frozen and initiative.issue.closed then 66.435 - local members_selector = initiative.issue:get_reference_selector("direct_voters") 66.436 - :left_join("vote", nil, { "vote.initiative_id = ? AND vote.member_id = member.id", initiative.id }) 66.437 - :add_field("direct_voter.weight as voter_weight") 66.438 - :add_field("coalesce(vote.grade, 0) as grade") 66.439 - :add_field("direct_voter.comment as voter_comment") 66.440 - :left_join("initiative", nil, "initiative.id = vote.initiative_id") 66.441 - :left_join("issue", nil, "issue.id = initiative.issue_id") 66.442 - 66.443 - ui.anchor{ name = "voter", attr = { class = "heading" }, content = _"Voters" } 66.444 - 66.445 - execute.view{ 66.446 - module = "member", 66.447 - view = "_list", 66.448 - params = { 66.449 - initiative = initiative, 66.450 - for_votes = true, 66.451 - members_selector = members_selector, 66.452 - paginator_name = "voter" 66.453 - } 66.454 - } 66.455 - end 66.456 - 66.457 - local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 66.458 - :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 66.459 - :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") 66.460 - :add_field("direct_interest_snapshot.weight") 66.461 - :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 66.462 - :add_where("direct_supporter_snapshot.satisfied") 66.463 - :add_field("direct_supporter_snapshot.informed", "is_informed") 66.464 - 66.465 - if members_selector:count() > 0 then 66.466 - if issue.fully_frozen then 66.467 - ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"Supporters (before begin of voting)" } 66.468 - else 66.469 - ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"Supporters" } 66.470 - end 66.471 - 66.472 - execute.view{ 66.473 - module = "member", 66.474 - view = "_list", 66.475 - params = { 66.476 - initiative = initiative, 66.477 - members_selector = members_selector, 66.478 - paginator_name = "supporters" 66.479 - } 66.480 - } 66.481 - else 66.482 - if issue.fully_frozen then 66.483 - ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"No supporters (before begin of voting)" } 66.484 - else 66.485 - ui.anchor{ name = "supporters", attr = { class = "heading" }, content = _"No supporters" } 66.486 - end 66.487 - slot.put("<br />") 66.488 - end 66.489 - 66.490 - local members_selector = initiative:get_reference_selector("supporting_members_snapshot") 66.491 - :join("issue", nil, "issue.id = direct_supporter_snapshot.issue_id") 66.492 - :join("direct_interest_snapshot", nil, "direct_interest_snapshot.event = issue.latest_snapshot_event AND direct_interest_snapshot.issue_id = issue.id AND direct_interest_snapshot.member_id = member.id") 66.493 - :add_field("direct_interest_snapshot.weight") 66.494 - :add_where("direct_supporter_snapshot.event = issue.latest_snapshot_event") 66.495 - :add_where("NOT direct_supporter_snapshot.satisfied") 66.496 - :add_field("direct_supporter_snapshot.informed", "is_informed") 66.497 - 66.498 - if members_selector:count() > 0 then 66.499 - if issue.fully_frozen then 66.500 - ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"Potential supporters (before begin of voting)" } 66.501 - else 66.502 - ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"Potential supporters" } 66.503 - end 66.504 - 66.505 - execute.view{ 66.506 - module = "member", 66.507 - view = "_list", 66.508 - params = { 66.509 - initiative = initiative, 66.510 - members_selector = members_selector, 66.511 - paginator_name = "potential_supporters" 66.512 - } 66.513 - } 66.514 - else 66.515 - if issue.fully_frozen then 66.516 - ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"No potential supporters (before begin of voting)" } 66.517 - else 66.518 - ui.anchor{ name = "potential_supporters", attr = { class = "heading" }, content = _"No potential supporters" } 66.519 - end 66.520 - slot.put("<br />") 66.521 - end 66.522 - 66.523 - ui.container{ attr = { class = "heading" }, content = _"Details" } 66.524 - execute.view { 66.525 - module = "initiative", 66.526 - view = "_details", 66.527 - params = { 66.528 - initiative = initiative, 66.529 - members_selector = members_selector 66.530 - } 66.531 - } 66.532 - 66.533 - end 66.534 -end 66.535 \ No newline at end of file
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/app/main/initiative/_sidebar_history.lua Thu Jul 10 01:19:48 2014 +0200 67.3 @@ -0,0 +1,14 @@ 67.4 +local initiative = param.get("initiative", "table") 67.5 + 67.6 + 67.7 +ui.sidebar( function () 67.8 + ui.sidebarHead( function () 67.9 + ui.link { attr = { name = "history" }, text = "" } 67.10 + ui.heading { level = 1, content = _"History" } 67.11 + end ) 67.12 + execute.view { 67.13 + module = "issue", view = "_list2", params = { 67.14 + for_initiative = initiative, for_sidebar = true 67.15 + } 67.16 + } 67.17 +end )
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/app/main/initiative/_sidebar_policies.lua Thu Jul 10 01:19:48 2014 +0200 68.3 @@ -0,0 +1,10 @@ 68.4 +local area = param.get("area", "table") 68.5 + 68.6 +ui.sidebar ( "tab-whatcanido", function () 68.7 + ui.sidebarHead( function() 68.8 + ui.heading { level = 2, content = _"Available policies" } 68.9 + end ) 68.10 + execute.view { module = "policy", view = "_list", params = { 68.11 + for_area = area 68.12 + } } 68.13 +end ) 68.14 \ No newline at end of file
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/app/main/initiative/_sidebar_state.lua Thu Jul 10 01:19:48 2014 +0200 69.3 @@ -0,0 +1,111 @@ 69.4 +local initiative = param.get("initiative", "table") 69.5 + 69.6 + 69.7 +-- voting results 69.8 +if initiative.issue.fully_frozen and initiative.issue.closed and initiative.admitted 69.9 + and initiative.issue.voter_count then 69.10 + local class = initiative.winner and "sectionRow admitted_info" or "sectionRow not_admitted_info" 69.11 + ui.container{ 69.12 + attr = { class = class }, 69.13 + content = function() 69.14 + local max_value = initiative.issue.voter_count 69.15 + local positive_votes = initiative.positive_votes 69.16 + local negative_votes = initiative.negative_votes 69.17 + local abstention_votes = max_value - 69.18 + negative_votes - 69.19 + positive_votes 69.20 + local function perc(votes, sum) 69.21 + if sum > 0 then return string.format( "%.f", votes * 100 / sum ) .. "%" end 69.22 + return "" 69.23 + end 69.24 + local head_text 69.25 + if initiative.winner then 69.26 + head_text = _"Approved" 69.27 + elseif initiative.rank then 69.28 + head_text = _("Rejected (rank #{rank})", { rank = initiative.rank }) 69.29 + else 69.30 + head_text = _"Rejected" 69.31 + end 69.32 + 69.33 + util.initiative_pie( initiative ) 69.34 + 69.35 + ui.heading { level = 1, content = head_text } 69.36 + 69.37 + ui.tag { tag = "table", content = function () 69.38 + ui.tag { tag = "tr", attr = { class = "yes" }, content = function () 69.39 + ui.tag { tag = "td", content = 69.40 + tostring(positive_votes) 69.41 + } 69.42 + ui.tag { tag = "th", content = _"Yes" } 69.43 + ui.tag { tag = "td", content = 69.44 + perc(positive_votes, max_value) 69.45 + } 69.46 + ui.tag { tag = "th", content = _"Yes" } 69.47 + end } 69.48 + ui.tag { tag = "tr", attr = { class = "abstention" }, content = function () 69.49 + ui.tag { tag = "td", content = 69.50 + tostring(abstention_votes) 69.51 + } 69.52 + ui.tag { tag = "th", content = _"Abstention" } 69.53 + ui.tag { tag = "td", content = 69.54 + perc(abstention_votes, max_value) 69.55 + } 69.56 + ui.tag { tag = "th", content = _"Abstention" } 69.57 + end } 69.58 + ui.tag { tag = "tr", attr = { class = "no" }, content = function () 69.59 + ui.tag { tag = "td", content = 69.60 + tostring(negative_votes) 69.61 + } 69.62 + ui.tag { tag = "th", content = _"No" } 69.63 + ui.tag { tag = "td", content = 69.64 + perc(negative_votes, max_value) 69.65 + } 69.66 + ui.tag { tag = "th", content = _"No" } 69.67 + end } 69.68 + end } 69.69 + end 69.70 + } 69.71 +end 69.72 + 69.73 +-- initiative not admitted info 69.74 +if initiative.admitted == false then 69.75 + local policy = initiative.issue.policy 69.76 + ui.container{ 69.77 + attr = { class = "sectionRow not_admitted_info" }, 69.78 + content = function () 69.79 + ui.heading { level = 1, content = _"Initiative not admitted" } 69.80 + ui.container { content = _("This initiative has not been admitted! It failed the 2nd quorum of #{quorum}.", { quorum = format.percentage ( policy.initiative_quorum_num / policy.initiative_quorum_den ) } ) } 69.81 + end 69.82 + } 69.83 +end 69.84 + 69.85 +-- initiative revoked info 69.86 +if initiative.revoked then 69.87 + ui.container{ 69.88 + attr = { class = "sectionRow revoked_info" }, 69.89 + content = function() 69.90 + ui.heading { level = 1, content = _"Initiative revoked" } 69.91 + slot.put(_("This initiative has been revoked at #{revoked} by:", { 69.92 + revoked = format.timestamp(initiative.revoked) 69.93 + })) 69.94 + slot.put(" ") 69.95 + ui.link{ 69.96 + module = "member", view = "show", id = initiative.revoked_by_member_id, 69.97 + content = initiative.revoked_by_member.name 69.98 + } 69.99 + local suggested_initiative = initiative.suggested_initiative 69.100 + if suggested_initiative then 69.101 + slot.put("<br /><br />") 69.102 + slot.put(_("The initiators suggest to support the following initiative:")) 69.103 + slot.put("<br />") 69.104 + ui.link{ 69.105 + content = suggested_initiative.display_name, 69.106 + module = "initiative", 69.107 + view = "show", 69.108 + id = suggested_initiative.id 69.109 + } 69.110 + end 69.111 + end 69.112 + } 69.113 +end 69.114 + 69.115 \ No newline at end of file
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/app/main/initiative/_sidebar_support.lua Thu Jul 10 01:19:48 2014 +0200 70.3 @@ -0,0 +1,108 @@ 70.4 +if not app.session.member then 70.5 + return 70.6 +end 70.7 + 70.8 +local initiative = param.get("initiative", "table") 70.9 + 70.10 +local initiative_info = initiative.member_info 70.11 +local issue_info = initiative.issue.member_info 70.12 + 70.13 +local active_trustee_id 70.14 +if not issue_info.own_participation then 70.15 + if issue_info.first_trustee_participation then 70.16 + active_trustee_id = issue_info.first_trustee_id 70.17 + elseif issue_info.other_trustee_participation then 70.18 + active_trustee_id = issue_info.other_trustee_id 70.19 + end 70.20 +end 70.21 + 70.22 + 70.23 +slot.select ( "sidebar", function () 70.24 + 70.25 + if 70.26 + not initiative.issue.fully_frozen 70.27 + and not initiative.issue.closed 70.28 + and (issue_info.own_participation or active_trustee_id) 70.29 + then 70.30 + ui.container { 70.31 + attr = { class = "tab-whatcanido sidebarSection" }, 70.32 + content = function () 70.33 + 70.34 + 70.35 + if initiative_info.supported then 70.36 + ui.heading { level = 1, content = function () 70.37 + ui.tag { content = _"I'm supporting this initiative" } 70.38 + if issue_info.weight then 70.39 + slot.put ( " " ) 70.40 + ui.link { 70.41 + module = "delegation", view = "show_incoming", params = { 70.42 + issue_id = initiative.issue_id, 70.43 + member_id = app.session.member_id 70.44 + }, 70.45 + content = "+" .. issue_info.weight 70.46 + } 70.47 + end 70.48 + end } 70.49 + 70.50 + else 70.51 + ui.heading { level = 1, content = function () 70.52 + ui.tag { content = _"I'm interested in this issue" } 70.53 + if issue_info.weight then 70.54 + slot.put ( " " ) 70.55 + ui.link { 70.56 + module = "delegation", view = "show_incoming", params = { 70.57 + issue_id = initiative.issue_id, 70.58 + member_id = app.session.member_id 70.59 + }, 70.60 + content = "+" .. issue_info.weight 70.61 + } 70.62 + end 70.63 + end } 70.64 + end 70.65 + 70.66 + if active_trustee_id then 70.67 + ui.tag { content = _"via delegation" } 70.68 + elseif issue_info.first_trustee_id then 70.69 + ui.tag { content = _"delegation suspended during discussion" } 70.70 + end 70.71 + end 70.72 + } 70.73 + end 70.74 + 70.75 + if 70.76 + initiative.issue.fully_frozen and 70.77 + (issue_info.direct_voted or active_trustee_id) 70.78 + then 70.79 + ui.container { 70.80 + attr = { class = "tab-whatcanido sidebarSection" }, 70.81 + content = function () 70.82 + 70.83 + if issue_info.direct_voted then 70.84 + ui.heading { level = 1, content = _"You have been voted" } 70.85 + ui.link { 70.86 + content = _"Show my voting ballot", 70.87 + module = "vote", view = "list", params = { 70.88 + issue_id = initiative.issue.id 70.89 + } 70.90 + } 70.91 + else 70.92 + 70.93 + 70.94 + if active_trustee_id then 70.95 + ui.heading { level = 1, content = _"You have been voted" } 70.96 + ui.container { 70.97 + content = _"via delegation" 70.98 + } 70.99 + ui.link { 70.100 + content = _"Show voting ballot", 70.101 + module = "vote", view = "list", params = { 70.102 + issue_id = initiative.issue.id, member_id = active_trustee_id 70.103 + } 70.104 + } 70.105 + end 70.106 + end 70.107 + end 70.108 + } 70.109 + end 70.110 +end ) 70.111 + 70.112 \ No newline at end of file
71.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 71.2 +++ b/app/main/initiative/_sidebar_wikisyntax.lua Thu Jul 10 01:19:48 2014 +0200 71.3 @@ -0,0 +1,61 @@ 71.4 +if config.enforce_formatting_engine ~= 'markdown2' then 71.5 + return 71.6 +end 71.7 + 71.8 +ui.sidebar( "tab-whatcanido", function() 71.9 + ui.sidebarHead( function() 71.10 + ui.heading { level = 2, content = _"Formatting help" } 71.11 + end ) 71.12 + ui.sidebarSection( function () 71.13 + ui.heading { level = 3, content = _"Paragraphs" } 71.14 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 71.15 + ui.tag { tag = "li", content = function () 71.16 + ui.tag { content = _"Separate each paragraph with at least one blank line" } 71.17 + end } 71.18 + end } 71.19 + 71.20 + ui.heading { level = 3, content = _"Headlines" } 71.21 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 71.22 + ui.tag { tag = "li", content = function () 71.23 + ui.tag { content = _"Underline main headlines with ===" } 71.24 + end } 71.25 + ui.tag { tag = "li", content = function () 71.26 + ui.tag { content = _"Underline sub headlines with ---" } 71.27 + end } 71.28 + end } 71.29 + 71.30 + ui.heading { level = 3, content = _"Emphasis" } 71.31 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 71.32 + ui.tag { tag = "li", content = function () 71.33 + ui.tag { content = _"Put *asterisks* or around a phrase to make it italic" } 71.34 + end } 71.35 + ui.tag { tag = "li", content = function () 71.36 + ui.tag { content = _"Put **double asterisks** around a phrase to make it bold" } 71.37 + end } 71.38 + end } 71.39 + 71.40 + ui.heading { level = 3, content = _"Lists" } 71.41 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 71.42 + ui.tag { tag = "li", content = function () 71.43 + ui.tag { content = _"Lists must be preceeded and followed by at least one blank line" } 71.44 + end } 71.45 + ui.tag { tag = "li", content = function () 71.46 + ui.tag { content = _"Put a hypen (-) or asterisk (*) followed by a space in front of each item" } 71.47 + end } 71.48 + ui.tag { tag = "li", content = function () 71.49 + ui.tag { content = _"For numbered items use a digit (e.g. 1) followed by a dot (.) and a space" } 71.50 + end } 71.51 + ui.tag { tag = "li", content = function () 71.52 + ui.tag { content = _"Indent sub items with spaces" } 71.53 + end } 71.54 + end } 71.55 + 71.56 + ui.heading { level = 3, content = _"Links" } 71.57 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 71.58 + ui.tag { tag = "li", content = function () 71.59 + ui.tag { content = _"Use [Text](http://example.com/) for links" } 71.60 + end } 71.61 + end } 71.62 + 71.63 + end ) 71.64 +end )
72.1 --- a/app/main/initiative/add_initiator.lua Thu Jul 10 01:02:43 2014 +0200 72.2 +++ b/app/main/initiative/add_initiator.lua Thu Jul 10 01:19:48 2014 +0200 72.3 @@ -1,26 +1,55 @@ 72.4 local initiative = Initiative:by_id(param.get("initiative_id")) 72.5 72.6 -slot.put_into("title", _"Invite an initiator to initiative") 72.7 +local member = app.session.member 72.8 +if member then 72.9 + initiative:load_everything_for_member_id(member.id) 72.10 + initiative.issue:load_everything_for_member_id(member.id) 72.11 +end 72.12 + 72.13 + 72.14 +local records = { 72.15 + { 72.16 + id = "-1", 72.17 + name = _"Choose member" 72.18 + } 72.19 +} 72.20 +local contact_members = app.session.member:get_reference_selector("saved_members"):add_order_by("name"):exec() 72.21 +for i, record in ipairs(contact_members) do 72.22 + records[#records+1] = record 72.23 +end 72.24 72.25 -slot.select("actions", function() 72.26 - ui.link{ 72.27 - content = function() 72.28 - ui.image{ static = "icons/16/cancel.png" } 72.29 - slot.put(_"Cancel") 72.30 - end, 72.31 - module = "initiative", 72.32 - view = "show", 72.33 - id = initiative.id, 72.34 - params = { 72.35 - tab = "initiators" 72.36 - } 72.37 +execute.view { 72.38 + module = "issue", view = "_head", params = { 72.39 + issue = initiative.issue, 72.40 + member = app.session.member 72.41 } 72.42 -end) 72.43 +} 72.44 + 72.45 +execute.view{ module = "issue", view = "_sidebar_state", params = { 72.46 + initiative = initiative 72.47 +} } 72.48 72.49 -util.help("initiative.add_initiator", _"Invite an initiator to initiative") 72.50 +execute.view { 72.51 + module = "issue", view = "_sidebar_issue", 72.52 + params = { 72.53 + issue = initiative.issue, 72.54 + highlight_initiative_id = initiative.id 72.55 + } 72.56 +} 72.57 + 72.58 +execute.view { 72.59 + module = "issue", view = "_sidebar_whatcanido", 72.60 + params = { initiative = initiative } 72.61 +} 72.62 + 72.63 +execute.view { 72.64 + module = "issue", view = "_sidebar_members", params = { 72.65 + issue = initiative.issue, initiative = initiative 72.66 + } 72.67 +} 72.68 72.69 ui.form{ 72.70 - attr = { class = "vertical" }, 72.71 + attr = { class = "wide section" }, 72.72 module = "initiative", 72.73 action = "add_initiator", 72.74 params = { 72.75 @@ -38,23 +67,50 @@ 72.76 } 72.77 }, 72.78 content = function() 72.79 - local records = { 72.80 - { 72.81 - id = "-1", 72.82 - name = _"Choose member" 72.83 + 72.84 + ui.sectionHead( function() 72.85 + ui.link{ 72.86 + module = "initiative", view = "show", id = initiative.id, 72.87 + content = function () 72.88 + ui.heading { 72.89 + level = 1, 72.90 + content = initiative.display_name 72.91 + } 72.92 + end 72.93 + } 72.94 + ui.heading { level = 2, content = _"Invite an initiator to initiative" } 72.95 + end ) 72.96 + 72.97 + ui.sectionRow( function() 72.98 + ui.heading { level = 2, content = _"Choose a member to invite" } 72.99 + ui.field.select{ 72.100 + name = "member_id", 72.101 + foreign_records = records, 72.102 + foreign_id = "id", 72.103 + foreign_name = "name" 72.104 } 72.105 - } 72.106 - local contact_members = app.session.member:get_reference_selector("saved_members"):add_order_by("name"):exec() 72.107 - for i, record in ipairs(contact_members) do 72.108 - records[#records+1] = record 72.109 - end 72.110 - ui.field.select{ 72.111 - label = _"Member", 72.112 - name = "member_id", 72.113 - foreign_records = records, 72.114 - foreign_id = "id", 72.115 - foreign_name = "name" 72.116 - } 72.117 - ui.submit{ text = _"Save" } 72.118 + ui.container{ content = _"You can choose only members which you have been saved as contact before." } 72.119 + slot.put("<br />") 72.120 + ui.tag{ 72.121 + tag = "input", 72.122 + attr = { 72.123 + type = "submit", 72.124 + class = "btn btn-default", 72.125 + value = _"Invite member" 72.126 + }, 72.127 + content = "" 72.128 + } 72.129 + slot.put("<br />") 72.130 + slot.put("<br />") 72.131 + ui.link{ 72.132 + content = _"Cancel", 72.133 + module = "initiative", 72.134 + view = "show", 72.135 + id = initiative.id, 72.136 + params = { 72.137 + tab = "initiators" 72.138 + } 72.139 + } 72.140 + end ) 72.141 end 72.142 } 72.143 \ No newline at end of file
73.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 73.2 +++ b/app/main/initiative/history.lua Thu Jul 10 01:19:48 2014 +0200 73.3 @@ -0,0 +1,117 @@ 73.4 +local initiative = Initiative:by_id(param.get_id()) 73.5 + 73.6 +initiative:load_everything_for_member_id(app.session.member_id) 73.7 +initiative.issue:load_everything_for_member_id(app.session.member_id) 73.8 + 73.9 + 73.10 +execute.view{ module = "issue", view = "_sidebar_state", params = { 73.11 + initiative = initiative 73.12 +} } 73.13 + 73.14 +execute.view { 73.15 + module = "issue", view = "_sidebar_issue", 73.16 + params = { 73.17 + issue = initiative.issue, 73.18 + highlight_initiative_id = initiative.id 73.19 + } 73.20 +} 73.21 + 73.22 +execute.view { 73.23 + module = "issue", view = "_sidebar_whatcanido", 73.24 + params = { initiative = initiative } 73.25 +} 73.26 + 73.27 +execute.view { 73.28 + module = "issue", view = "_sidebar_members", params = { 73.29 + issue = initiative.issue, initiative = initiative 73.30 + } 73.31 +} 73.32 + 73.33 + 73.34 + 73.35 +execute.view { 73.36 + module = "issue", view = "_head", params = { 73.37 + issue = initiative.issue 73.38 + } 73.39 +} 73.40 + 73.41 +ui.form{ 73.42 + method = "get", 73.43 + module = "draft", 73.44 + view = "diff", 73.45 + attr = { class = "section" }, 73.46 + content = function() 73.47 + ui.field.hidden{ name = "initiative_id", value = initiative.id } 73.48 + 73.49 + ui.sectionHead( function() 73.50 + ui.link{ 73.51 + module = "initiative", view = "show", id = initiative.id, 73.52 + content = function () 73.53 + ui.heading { 73.54 + level = 1, 73.55 + content = initiative.display_name 73.56 + } 73.57 + end 73.58 + } 73.59 + ui.heading { level = 2, content = _"Draft history" } 73.60 + end) 73.61 + 73.62 + ui.sectionRow( function() 73.63 + 73.64 + local columns = { 73.65 + { 73.66 + label = _"draft ID", 73.67 + content = function(record) 73.68 + ui.tag { content = record.id } 73.69 + end 73.70 + }, 73.71 + { 73.72 + label = _"published at", 73.73 + content = function(record) 73.74 + ui.link{ 73.75 + attr = { class = "action" }, 73.76 + module = "draft", view = "show", id = record.id, 73.77 + text = format.timestamp(record.created) 73.78 + } 73.79 + end 73.80 + }, 73.81 + { 73.82 + label = _"compare", 73.83 + content = function(record) 73.84 + slot.put('<input type="radio" name="old_draft_id" value="' .. tostring(record.id) .. '">') 73.85 + slot.put('<input type="radio" name="new_draft_id" value="' .. tostring(record.id) .. '">') 73.86 + end 73.87 + } 73.88 + } 73.89 + 73.90 + if app.session:has_access("authors_pseudonymous") then 73.91 + columns[#columns+1] = { 73.92 + label = _"author", 73.93 + content = function(record) 73.94 + if record.author then 73.95 + return util.micro_avatar ( record.author ) 73.96 + end 73.97 + end 73.98 + } 73.99 + end 73.100 + 73.101 + ui.list{ 73.102 + records = initiative.drafts, 73.103 + columns = columns 73.104 + } 73.105 + 73.106 + slot.put("<br />") 73.107 + ui.container { attr = { class = "actions" }, content = function() 73.108 + ui.tag{ 73.109 + tag = "input", 73.110 + attr = { 73.111 + type = "submit", 73.112 + class = "btn btn-default", 73.113 + value = _"compare revisions" 73.114 + }, 73.115 + content = "" 73.116 + } 73.117 + end } 73.118 + end ) 73.119 + end 73.120 +}
74.1 --- a/app/main/initiative/new.lua Thu Jul 10 01:02:43 2014 +0200 74.2 +++ b/app/main/initiative/new.lua Thu Jul 10 01:19:48 2014 +0200 74.3 @@ -4,11 +4,13 @@ 74.4 local issue_id = param.get("issue_id", atom.integer) 74.5 if issue_id then 74.6 issue = Issue:new_selector():add_where{"id=?",issue_id}:single_object_mode():exec() 74.7 + issue:load_everything_for_member_id(app.session.member_id) 74.8 area = issue.area 74.9 74.10 else 74.11 local area_id = param.get("area_id", atom.integer) 74.12 area = Area:new_selector():add_where{"id=?",area_id}:single_object_mode():exec() 74.13 + area:load_delegation_info_once_for_member_id(app.session.member_id) 74.14 end 74.15 74.16 local polling = param.get("polling", atom.boolean) 74.17 @@ -16,17 +18,49 @@ 74.18 local policy_id = param.get("policy_id", atom.integer) 74.19 local policy 74.20 74.21 +local preview = param.get("preview") 74.22 + 74.23 +if #(slot.get_content("error")) > 0 then 74.24 + preview = false 74.25 +end 74.26 + 74.27 if policy_id then 74.28 policy = Policy:by_id(policy_id) 74.29 end 74.30 74.31 if issue_id then 74.32 - ui.title(_"Add alternative initiative to issue") 74.33 + execute.view { 74.34 + module = "issue", view = "_head", 74.35 + params = { issue = issue, member = app.session.member } 74.36 + } 74.37 + execute.view { 74.38 + module = "issue", view = "_sidebar_state", 74.39 + params = { 74.40 + issue = issue 74.41 + } 74.42 + } 74.43 + execute.view { 74.44 + module = "issue", view = "_sidebar_issue", 74.45 + params = { 74.46 + issue = issue 74.47 + } 74.48 + } 74.49 else 74.50 - ui.title(_"Create new issue") 74.51 + execute.view { 74.52 + module = "area", view = "_head", 74.53 + params = { area = area, member = app.session.member } 74.54 + } 74.55 + execute.view { 74.56 + module = "initiative", view = "_sidebar_policies", 74.57 + params = { 74.58 + area = area, 74.59 + } 74.60 + } 74.61 end 74.62 74.63 -local preview = param.get("preview") 74.64 + 74.65 + 74.66 + 74.67 74.68 if not preview and not issue_id and app.session.member:has_polling_right_for_unit_id(area.unit_id) then 74.69 ui.actions(function() 74.70 @@ -59,181 +93,214 @@ 74.71 }, 74.72 attr = { class = "vertical" }, 74.73 content = function() 74.74 - ui.field.text{ label = _"Unit", value = area.unit.name } 74.75 - ui.field.text{ label = _"Area", value = area.name } 74.76 - slot.put("<br />") 74.77 - if issue_id then 74.78 - ui.field.text{ label = _"Issue", value = issue_id } 74.79 - elseif policy then 74.80 - ui.field.hidden{ name = "policy_id", value = policy.id } 74.81 - ui.field.text{ label = _"Policy", value = policy.name } 74.82 - if policy.free_timeable then 74.83 - local available_timings 74.84 - if config.free_timing and config.free_timing.available_func then 74.85 - available_timings = config.free_timing.available_func(policy) 74.86 - if available_timings == false then 74.87 - error("error in free timing config") 74.88 + 74.89 + if preview then 74.90 + ui.section( function() 74.91 + ui.sectionHead( function() 74.92 + ui.heading{ level = 1, content = encode.html(param.get("name")) } 74.93 + if not issue then 74.94 + ui.container { content = policy.name } 74.95 end 74.96 - end 74.97 - if available_timings then 74.98 - ui.field.select{ 74.99 - label = _"Free timing", 74.100 - name = "free_timing", 74.101 - foreign_records = available_timings, 74.102 - foreign_id = "id", 74.103 - foreign_name = "name", 74.104 - value = param.get("free_timing") 74.105 - } 74.106 - else 74.107 - ui.field.text{ label = _"Free timing", name = "free_timing", value = param.get("free_timing") } 74.108 - end 74.109 - end 74.110 - else 74.111 - tmp = { { id = -1, name = _"Please choose a policy" } } 74.112 - for i, allowed_policy in ipairs(area.allowed_policies) do 74.113 - if not allowed_policy.polling then 74.114 - tmp[#tmp+1] = allowed_policy 74.115 - end 74.116 - end 74.117 - ui.field.select{ 74.118 - label = _"Policy", 74.119 - name = "policy_id", 74.120 - foreign_records = tmp, 74.121 - foreign_id = "id", 74.122 - foreign_name = "name", 74.123 - value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id 74.124 - } 74.125 - ui.tag{ 74.126 - tag = "div", 74.127 - content = function() 74.128 - ui.tag{ 74.129 - tag = "label", 74.130 - attr = { class = "ui_field_label" }, 74.131 - content = function() slot.put(" ") end, 74.132 - } 74.133 - ui.tag{ 74.134 + slot.put("<br />") 74.135 + 74.136 + ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") } 74.137 + ui.field.hidden{ name = "policy_id", value = param.get("policy_id") } 74.138 + ui.field.hidden{ name = "name", value = param.get("name") } 74.139 + ui.field.hidden{ name = "draft", value = param.get("draft") } 74.140 + local formatting_engine 74.141 + if config.enforce_formatting_engine then 74.142 + formatting_engine = config.enforce_formatting_engine 74.143 + else 74.144 + formatting_engine = param.get("formatting_engine") 74.145 + end 74.146 + ui.container{ 74.147 + attr = { class = "draft_content wiki" }, 74.148 content = function() 74.149 - ui.link{ 74.150 - text = _"Information about the available policies", 74.151 - module = "policy", 74.152 - view = "list" 74.153 - } 74.154 - slot.put(" ") 74.155 - ui.link{ 74.156 - attr = { target = "_blank" }, 74.157 - text = _"(new window)", 74.158 - module = "policy", 74.159 - view = "list" 74.160 - } 74.161 + slot.put(format.wiki_text(param.get("draft"), formatting_engine)) 74.162 end 74.163 } 74.164 - end 74.165 - } 74.166 - end 74.167 - 74.168 - if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then 74.169 - ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling } 74.170 - end 74.171 - 74.172 - if preview then 74.173 - ui.heading{ level = 1, content = encode.html(param.get("name")) } 74.174 - local discussion_url = param.get("discussion_url") 74.175 - ui.container{ 74.176 - attr = { class = "ui_field_label" }, 74.177 - content = _"Discussion with initiators" 74.178 - } 74.179 - ui.tag{ 74.180 - tag = "span", 74.181 - content = function() 74.182 - if discussion_url:find("^https?://") then 74.183 - if discussion_url and #discussion_url > 0 then 74.184 - ui.link{ 74.185 - attr = { 74.186 - class = "actions", 74.187 - target = "_blank", 74.188 - title = discussion_url 74.189 - }, 74.190 - content = discussion_url, 74.191 - external = discussion_url 74.192 - } 74.193 - end 74.194 + slot.put("<br />") 74.195 + 74.196 + ui.tag{ 74.197 + tag = "input", 74.198 + attr = { 74.199 + type = "submit", 74.200 + class = "btn btn-default", 74.201 + value = _'Publish now' 74.202 + }, 74.203 + content = "" 74.204 + } 74.205 + slot.put("<br />") 74.206 + slot.put("<br />") 74.207 + ui.tag{ 74.208 + tag = "input", 74.209 + attr = { 74.210 + type = "submit", 74.211 + name = "edit", 74.212 + class = "btn-link", 74.213 + value = _'Edit again' 74.214 + }, 74.215 + content = "" 74.216 + } 74.217 + slot.put(" | ") 74.218 + if issue then 74.219 + ui.link{ content = _"Cancel", module = "issue", view = "show", id = issue.id } 74.220 else 74.221 - slot.put(encode.html(discussion_url)) 74.222 + ui.link{ content = _"Cancel", module = "area", view = "show", id = area.id } 74.223 end 74.224 - end 74.225 - } 74.226 - ui.container{ 74.227 - attr = { class = "draft_content wiki" }, 74.228 - content = function() 74.229 - slot.put(format.wiki_text(param.get("draft"), param.get("formatting_engine"))) 74.230 - end 74.231 - } 74.232 - slot.put("<br />") 74.233 - ui.submit{ text = _"Save" } 74.234 - slot.put("<br />") 74.235 - slot.put("<br />") 74.236 - end 74.237 - slot.put("<br />") 74.238 + end ) 74.239 + end ) 74.240 + else 74.241 + 74.242 + 74.243 + execute.view{ module = "initiative", view = "_sidebar_wikisyntax" } 74.244 74.245 - ui.field.text{ 74.246 - label = _"Title of initiative", 74.247 - name = "name", 74.248 - value = param.get("name") 74.249 - } 74.250 - ui.field.text{ 74.251 - label = _"Discussion URL", 74.252 - name = "discussion_url", 74.253 - value = param.get("discussion_url") 74.254 - } 74.255 - ui.field.select{ 74.256 - label = _"Wiki engine", 74.257 - name = "formatting_engine", 74.258 - foreign_records = { 74.259 - { id = "rocketwiki", name = "RocketWiki" }, 74.260 - { id = "compat", name = _"Traditional wiki syntax" } 74.261 - }, 74.262 - attr = {id = "formatting_engine"}, 74.263 - foreign_id = "id", 74.264 - foreign_name = "name", 74.265 - value = param.get("formatting_engine") 74.266 - } 74.267 - ui.tag{ 74.268 - tag = "div", 74.269 - content = function() 74.270 - ui.tag{ 74.271 - tag = "label", 74.272 - attr = { class = "ui_field_label" }, 74.273 - content = function() slot.put(" ") end, 74.274 + ui.section( function() 74.275 + if preview then 74.276 + ui.sectionHead( function() 74.277 + ui.heading { level = 1, content = _"Edit again" } 74.278 + end ) 74.279 + elseif issue_id then 74.280 + ui.sectionHead( function() 74.281 + ui.heading { level = 1, content = _"Add a new competing initiative to issue" } 74.282 + end ) 74.283 + else 74.284 + ui.sectionHead( function() 74.285 + ui.heading { level = 1, content = _"Create a new issue" } 74.286 + end ) 74.287 + end 74.288 + 74.289 + ui.sectionRow( function() 74.290 + if not preview and not issue_id then 74.291 + ui.container { attr = { class = "section" }, content = _"Before creating a new issue, please check any existant issues before, if the topic is already in discussion." } 74.292 + slot.put("<br />") 74.293 + end 74.294 + if not issue_id then 74.295 + tmp = { { id = -1, name = "" } } 74.296 + for i, allowed_policy in ipairs(area.allowed_policies) do 74.297 + if not allowed_policy.polling then 74.298 + tmp[#tmp+1] = allowed_policy 74.299 + end 74.300 + end 74.301 + ui.heading{ level = 2, content = _"Please choose a policy for the new issue:" } 74.302 + ui.field.select{ 74.303 + name = "policy_id", 74.304 + foreign_records = tmp, 74.305 + foreign_id = "id", 74.306 + foreign_name = "name", 74.307 + value = param.get("policy_id", atom.integer) or area.default_policy and area.default_policy.id 74.308 + } 74.309 + if policy and policy.free_timeable then 74.310 + ui.sectionRow( function() 74.311 + local available_timings 74.312 + if config.free_timing and config.free_timing.available_func then 74.313 + available_timings = config.free_timing.available_func(policy) 74.314 + if available_timings == false then 74.315 + error("error in free timing config") 74.316 + end 74.317 + end 74.318 + ui.heading{ level = 4, content = _"Free timing:" } 74.319 + if available_timings then 74.320 + ui.field.select{ 74.321 + name = "free_timing", 74.322 + foreign_records = available_timings, 74.323 + foreign_id = "id", 74.324 + foreign_name = "name", 74.325 + value = param.get("free_timing") 74.326 + } 74.327 + else 74.328 + ui.field.text{ 74.329 + name = "free_timing", 74.330 + value = param.get("free_timing") 74.331 + } 74.332 + end 74.333 + end ) 74.334 + end 74.335 + end 74.336 + 74.337 + if issue and issue.policy.polling and app.session.member:has_polling_right_for_unit_id(area.unit_id) then 74.338 + slot.put("<br />") 74.339 + ui.field.boolean{ name = "polling", label = _"No admission needed", value = polling } 74.340 + end 74.341 + 74.342 + slot.put("<br />") 74.343 + ui.heading { level = 2, content = _"Enter a title for your initiative (max. 140 chars):" } 74.344 + ui.field.text{ 74.345 + attr = { style = "width: 100%;" }, 74.346 + name = "name", 74.347 + value = param.get("name") 74.348 } 74.349 + ui.container { content = _"The title is the figurehead of your iniative. It should be short but meaningful! As others identifies your initiative by this title, you cannot change it later!" } 74.350 + 74.351 + if not config.enforce_formatting_engine then 74.352 + slot.put("<br />") 74.353 + ui.heading { level = 4, content = _"Choose a formatting engine:" } 74.354 + ui.field.select{ 74.355 + name = "formatting_engine", 74.356 + foreign_records = config.formatting_engines, 74.357 + attr = {id = "formatting_engine"}, 74.358 + foreign_id = "id", 74.359 + foreign_name = "name", 74.360 + value = param.get("formatting_engine") 74.361 + } 74.362 + end 74.363 + slot.put("<br />") 74.364 + 74.365 + ui.heading { level = 2, content = _"Enter your proposal and/or reasons:" } 74.366 + ui.field.text{ 74.367 + name = "draft", 74.368 + multiline = true, 74.369 + attr = { style = "height: 50ex; width: 100%;" }, 74.370 + value = param.get("draft") or 74.371 + [[ 74.372 +Proposal 74.373 +====== 74.374 + 74.375 +Replace me with your proposal. 74.376 + 74.377 + 74.378 +Reasons 74.379 +====== 74.380 + 74.381 +Argument 1 74.382 +------ 74.383 + 74.384 +Replace me with your first argument 74.385 + 74.386 + 74.387 +Argument 2 74.388 +------ 74.389 + 74.390 +Replace me with your second argument 74.391 + 74.392 +]] 74.393 + } 74.394 + if not issue or issue.state == "admission" or issue.state == "discussion" then 74.395 + ui.container { content = _"You can change your text again anytime during admission and discussion phase" } 74.396 + else 74.397 + ui.container { content = _"You cannot change your text again later, because this issue is already in verfication phase!" } 74.398 + end 74.399 + slot.put("<br />") 74.400 ui.tag{ 74.401 - content = function() 74.402 - ui.link{ 74.403 - text = _"Syntax help", 74.404 - module = "help", 74.405 - view = "show", 74.406 - id = "wikisyntax", 74.407 - attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 74.408 - } 74.409 - slot.put(" ") 74.410 - ui.link{ 74.411 - text = _"(new window)", 74.412 - module = "help", 74.413 - view = "show", 74.414 - id = "wikisyntax", 74.415 - attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 74.416 - } 74.417 - end 74.418 + tag = "input", 74.419 + attr = { 74.420 + type = "submit", 74.421 + name = "preview", 74.422 + class = "btn btn-default", 74.423 + value = _'Preview' 74.424 + }, 74.425 + content = "" 74.426 } 74.427 - end 74.428 - } 74.429 - ui.field.text{ 74.430 - label = _"Draft", 74.431 - name = "draft", 74.432 - multiline = true, 74.433 - attr = { style = "height: 50ex;" }, 74.434 - value = param.get("draft") 74.435 - } 74.436 - ui.submit{ name = "preview", text = _"Preview" } 74.437 - ui.submit{ text = _"Save" } 74.438 + slot.put("<br />") 74.439 + slot.put("<br />") 74.440 + 74.441 + if issue then 74.442 + ui.link{ content = _"Cancel", module = "issue", view = "show", id = issue.id } 74.443 + else 74.444 + ui.link{ content = _"Cancel", module = "area", view = "show", id = area.id } 74.445 + end 74.446 + end ) 74.447 + end ) 74.448 + end 74.449 end 74.450 }
75.1 --- a/app/main/initiative/remove_initiator.lua Thu Jul 10 01:02:43 2014 +0200 75.2 +++ b/app/main/initiative/remove_initiator.lua Thu Jul 10 01:19:48 2014 +0200 75.3 @@ -1,31 +1,48 @@ 75.4 local initiative = Initiative:by_id(param.get("initiative_id")) 75.5 75.6 +local member = app.session.member 75.7 +if member then 75.8 + initiative:load_everything_for_member_id(member.id) 75.9 + initiative.issue:load_everything_for_member_id(member.id) 75.10 +end 75.11 + 75.12 local initiator = Initiator:by_pk(initiative.id, app.session.member.id) 75.13 if not initiator or initiator.accepted ~= true then 75.14 error("access denied") 75.15 end 75.16 75.17 -slot.put_into("title", _"Remove initiator from initiative") 75.18 +execute.view { 75.19 + module = "issue", view = "_head", params = { 75.20 + issue = initiative.issue, 75.21 + member = app.session.member 75.22 + } 75.23 +} 75.24 + 75.25 +execute.view{ module = "issue", view = "_sidebar_state", params = { 75.26 + initiative = initiative 75.27 +} } 75.28 75.29 -slot.select("actions", function() 75.30 - ui.link{ 75.31 - content = function() 75.32 - ui.image{ static = "icons/16/cancel.png" } 75.33 - slot.put(_"Cancel") 75.34 - end, 75.35 - module = "initiative", 75.36 - view = "show", 75.37 - id = initiative.id, 75.38 - params = { 75.39 - tab = "initiators" 75.40 - } 75.41 +execute.view { 75.42 + module = "issue", view = "_sidebar_issue", 75.43 + params = { 75.44 + issue = initiative.issue, 75.45 + highlight_initiative_id = initiative.id 75.46 } 75.47 -end) 75.48 +} 75.49 75.50 -util.help("initiative.remove_initiator", _"Remove initiator from initiative") 75.51 +execute.view { 75.52 + module = "issue", view = "_sidebar_whatcanido", 75.53 + params = { initiative = initiative } 75.54 +} 75.55 + 75.56 +execute.view { 75.57 + module = "issue", view = "_sidebar_members", params = { 75.58 + issue = initiative.issue, initiative = initiative 75.59 + } 75.60 +} 75.61 75.62 ui.form{ 75.63 - attr = { class = "vertical" }, 75.64 + attr = { class = "vertical section" }, 75.65 module = "initiative", 75.66 action = "remove_initiator", 75.67 params = { 75.68 @@ -43,23 +60,50 @@ 75.69 } 75.70 }, 75.71 content = function() 75.72 - local records = { 75.73 - { 75.74 - id = "-1", 75.75 - name = _"Choose initiator" 75.76 + 75.77 + ui.sectionHead( function() 75.78 + ui.link{ 75.79 + module = "initiative", view = "show", id = initiative.id, 75.80 + content = function () 75.81 + ui.heading { 75.82 + level = 1, 75.83 + content = initiative.display_name 75.84 + } 75.85 + end 75.86 + } 75.87 + ui.heading { level = 2, content = _"Remove an initiator from initiative" } 75.88 + end ) 75.89 + 75.90 + ui.sectionRow( function() 75.91 + local records = initiative:get_reference_selector("initiating_members"):add_where("accepted OR accepted ISNULL"):exec() 75.92 + ui.heading{ level = 2, content = _"Choose an initiator to remove" } 75.93 + ui.field.select{ 75.94 + name = "member_id", 75.95 + foreign_records = records, 75.96 + foreign_id = "id", 75.97 + foreign_name = "name", 75.98 } 75.99 - } 75.100 - local members = initiative:get_reference_selector("initiating_members"):add_where("accepted OR accepted ISNULL"):exec() 75.101 - for i, record in ipairs(members) do 75.102 - records[#records+1] = record 75.103 - end 75.104 - ui.field.select{ 75.105 - label = _"Member", 75.106 - name = "member_id", 75.107 - foreign_records = records, 75.108 - foreign_id = "id", 75.109 - foreign_name = "name" 75.110 - } 75.111 - ui.submit{ text = _"Save" } 75.112 + slot.put("<br />") 75.113 + ui.tag{ 75.114 + tag = "input", 75.115 + attr = { 75.116 + type = "submit", 75.117 + class = "btn btn-dangerous", 75.118 + value = _"Remove initiator" 75.119 + }, 75.120 + content = "" 75.121 + } 75.122 + slot.put("<br />") 75.123 + slot.put("<br />") 75.124 + ui.link{ 75.125 + content = _"Cancel", 75.126 + module = "initiative", 75.127 + view = "show", 75.128 + id = initiative.id, 75.129 + params = { 75.130 + tab = "initiators" 75.131 + } 75.132 + } 75.133 + end ) 75.134 end 75.135 } 75.136 \ No newline at end of file
76.1 --- a/app/main/initiative/revoke.lua Thu Jul 10 01:02:43 2014 +0200 76.2 +++ b/app/main/initiative/revoke.lua Thu Jul 10 01:19:48 2014 +0200 76.3 @@ -1,26 +1,60 @@ 76.4 local initiative = Initiative:by_id(param.get_id()) 76.5 +local initiatives = app.session.member 76.6 + :get_reference_selector("supported_initiatives") 76.7 + :join("issue", nil, "issue.id = initiative.issue_id") 76.8 + :add_where("issue.closed ISNULL") 76.9 + :add_order_by("issue.id") 76.10 + :exec() 76.11 76.12 -slot.put_into("title", _"Revoke initiative") 76.13 + 76.14 +local member = app.session.member 76.15 +if member then 76.16 + initiative:load_everything_for_member_id(member.id) 76.17 + initiative.issue:load_everything_for_member_id(member.id) 76.18 +end 76.19 + 76.20 + 76.21 +local tmp = { { id = -1, myname = _"Suggest no initiative" }} 76.22 +for i, initiative in ipairs(initiatives) do 76.23 + initiative.myname = _("Issue ##{issue_id}: #{initiative_name}", { 76.24 + issue_id = initiative.issue.id, 76.25 + initiative_name = initiative.name 76.26 + }) 76.27 + tmp[#tmp+1] = initiative 76.28 +end 76.29 76.30 -slot.select("actions", function() 76.31 - ui.link{ 76.32 - content = function() 76.33 - ui.image{ static = "icons/16/cancel.png" } 76.34 - slot.put(_"Cancel") 76.35 - end, 76.36 - module = "initiative", 76.37 - view = "show", 76.38 - id = initiative.id, 76.39 - params = { 76.40 - tab = "initiators" 76.41 - } 76.42 +execute.view { 76.43 + module = "issue", view = "_head", params = { 76.44 + issue = initiative.issue, 76.45 + member = member 76.46 } 76.47 -end) 76.48 +} 76.49 +execute.view{ module = "issue", view = "_sidebar_state", params = { 76.50 + initiative = initiative 76.51 +} } 76.52 76.53 -util.help("initiative.revoke") 76.54 +execute.view { 76.55 + module = "issue", view = "_sidebar_issue", 76.56 + params = { 76.57 + issue = initiative.issue, 76.58 + highlight_initiative_id = initiative.id 76.59 + } 76.60 +} 76.61 + 76.62 +execute.view { 76.63 + module = "issue", view = "_sidebar_whatcanido", 76.64 + params = { initiative = initiative } 76.65 +} 76.66 + 76.67 +execute.view { 76.68 + module = "issue", view = "_sidebar_members", params = { 76.69 + issue = initiative.issue, initiative = initiative 76.70 + } 76.71 +} 76.72 + 76.73 76.74 ui.form{ 76.75 - attr = { class = "vertical" }, 76.76 + attr = { class = "wide section" }, 76.77 module = "initiative", 76.78 action = "revoke", 76.79 id = initiative.id, 76.80 @@ -33,30 +67,67 @@ 76.81 } 76.82 }, 76.83 content = function() 76.84 - local initiatives = app.session.member 76.85 - :get_reference_selector("supported_initiatives") 76.86 - :join("issue", nil, "issue.id = initiative.issue_id") 76.87 - :add_field("'Issue #' || issue.id || ': ' || initiative.name", "myname") 76.88 - :exec() 76.89 + 76.90 + ui.sectionHead( function() 76.91 + ui.link{ 76.92 + module = "initiative", view = "show", id = initiative.id, 76.93 + content = function () 76.94 + ui.heading { 76.95 + level = 1, 76.96 + content = initiative.display_name 76.97 + } 76.98 + end 76.99 + } 76.100 + ui.heading { level = 2, content = _"Revoke initiative" } 76.101 + end ) 76.102 + 76.103 + ui.sectionRow( function() 76.104 76.105 - local tmp = { { id = -1, myname = _"Suggest no initiative" }} 76.106 - for i, initiative in ipairs(initiatives) do 76.107 - tmp[#tmp+1] = initiative 76.108 - end 76.109 - ui.field.select{ 76.110 - label = _"Suggested initiative", 76.111 - name = "suggested_initiative_id", 76.112 - foreign_records = tmp, 76.113 - foreign_id = "id", 76.114 - foreign_name = "myname", 76.115 - value = param.get("suggested_initiative_id", atom.integer) 76.116 - } 76.117 - slot.put("") 76.118 - ui.field.boolean{ 76.119 - label = _"Are you sure?", 76.120 - name = "are_you_sure", 76.121 - } 76.122 + ui.heading{ level = 2, content = _"Do you want to suggest to support another initiative?" } 76.123 + 76.124 + ui.field.select{ 76.125 + name = "suggested_initiative_id", 76.126 + foreign_records = tmp, 76.127 + foreign_id = "id", 76.128 + foreign_name = "myname", 76.129 + value = param.get("suggested_initiative_id", atom.integer) 76.130 + } 76.131 + ui.container{ content = _"You may choose one of the ongoing initiatives you are currently supporting" } 76.132 + slot.put("<br />") 76.133 + ui.heading { level = 2, content = _"Are you aware that revoking an initiative is irrevocable?" } 76.134 + ui.container{ content = function() 76.135 + ui.tag{ tag = "input", attr = { 76.136 + type = "checkbox", 76.137 + name = "are_you_sure", 76.138 + value = "1" 76.139 + } } 76.140 + ui.tag { content = _"I understand, that this is not revocable" } 76.141 + end } 76.142 + 76.143 + 76.144 + slot.put("<br />") 76.145 + ui.tag{ 76.146 + tag = "input", 76.147 + attr = { 76.148 + type = "submit", 76.149 + class = "btn btn-dangerous", 76.150 + value = _"Revoke now" 76.151 + }, 76.152 + content = "" 76.153 + } 76.154 + slot.put("<br />") 76.155 + slot.put("<br />") 76.156 76.157 - ui.submit{ text = _"Revoke initiative" } 76.158 + ui.link{ 76.159 + content = _"Cancel", 76.160 + module = "initiative", 76.161 + view = "show", 76.162 + id = initiative.id, 76.163 + params = { 76.164 + tab = "initiators" 76.165 + } 76.166 + } 76.167 + end ) 76.168 + 76.169 end 76.170 } 76.171 \ No newline at end of file
77.1 --- a/app/main/initiative/show.lua Thu Jul 10 01:02:43 2014 +0200 77.2 +++ b/app/main/initiative/show.lua Thu Jul 10 01:19:48 2014 +0200 77.3 @@ -1,7 +1,541 @@ 77.4 -local initiative = Initiative:by_id(param.get_id()) 77.5 +local initiative = Initiative:by_id ( param.get_id() ) 77.6 +local member = app.session.member 77.7 + 77.8 +if not initiative then 77.9 + execute.view { module = "index", view = "404" } 77.10 + request.set_status("404 Not Found") 77.11 + return 77.12 +end 77.13 + 77.14 +local issue_info 77.15 + 77.16 +if member then 77.17 + initiative:load_everything_for_member_id(member.id) 77.18 + initiative.issue:load_everything_for_member_id(member.id) 77.19 + issue_info = initiative.issue.member_info 77.20 +end 77.21 + 77.22 +execute.view { 77.23 + module = "issue", view = "_head", 77.24 + params = { 77.25 + issue = initiative.issue, 77.26 + initiative = initiative, 77.27 + member = app.session.member 77.28 + } 77.29 +} 77.30 + 77.31 +if app.session.member_id then 77.32 + direct_supporter = initiative.issue.member_info.own_participation and initiative.member_info.supported 77.33 +end 77.34 77.35 -execute.view{ 77.36 - module = "initiative", view = "_show", params = { 77.37 - initiative = initiative 77.38 +ui.script { script = [[ 77.39 + function showTab(tabId) { 77.40 + $('.tab').hide(); 77.41 + $('.main').hide(); 77.42 + $('.main, .slot_extra .section').hide(); 77.43 + $('.' + tabId).show(); 77.44 + if (tabId == "main") $('.slot_extra .section').show(); 77.45 + }; 77.46 + showTab('main'); 77.47 +]]} 77.48 + 77.49 +execute.view{ module = "issue", view = "_sidebar_state", params = { 77.50 + initiative = initiative 77.51 +} } 77.52 + 77.53 +execute.view { 77.54 + module = "issue", view = "_sidebar_issue", 77.55 + params = { 77.56 + issue = initiative.issue, 77.57 + highlight_initiative_id = initiative.id 77.58 + } 77.59 +} 77.60 + 77.61 +execute.view { 77.62 + module = "issue", view = "_sidebar_whatcanido", 77.63 + params = { initiative = initiative } 77.64 +} 77.65 + 77.66 +execute.view { 77.67 + module = "issue", view = "_sidebar_members", params = { 77.68 + issue = initiative.issue, initiative = initiative 77.69 } 77.70 } 77.71 + 77.72 +ui.section( function () 77.73 + execute.view{ 77.74 + module = "initiative", view = "_head", params = { 77.75 + initiative = initiative 77.76 + } 77.77 + } 77.78 + 77.79 + if direct_supporter and not initiative.issue.closed then 77.80 + local supporter = app.session.member:get_reference_selector("supporters") 77.81 + :add_where{ "initiative_id = ?", initiative.id } 77.82 + :optional_object_mode() 77.83 + :exec() 77.84 + 77.85 + if supporter then 77.86 + 77.87 + local old_draft_id = supporter.draft_id 77.88 + local new_draft_id = initiative.current_draft.id 77.89 + 77.90 + if old_draft_id ~= new_draft_id then 77.91 + ui.sectionRow( "draft_updated_info", function () 77.92 + ui.container{ 77.93 + attr = { class = "info" }, 77.94 + content = _"The draft of this initiative has been updated!" 77.95 + } 77.96 + slot.put(" ") 77.97 + ui.link{ 77.98 + content = _"show differences", 77.99 + module = "draft", 77.100 + view = "diff", 77.101 + params = { 77.102 + old_draft_id = old_draft_id, 77.103 + new_draft_id = new_draft_id 77.104 + } 77.105 + } 77.106 + if not initiative.revoked then 77.107 + slot.put(" | ") 77.108 + ui.link{ 77.109 + text = _"refresh my support", 77.110 + module = "initiative", 77.111 + action = "add_support", 77.112 + id = initiative.id, 77.113 + params = { draft_id = initiative.current_draft.id }, 77.114 + routing = { 77.115 + default = { 77.116 + mode = "redirect", 77.117 + module = "initiative", 77.118 + view = "show", 77.119 + id = initiative.id 77.120 + } 77.121 + } 77.122 + } 77.123 + slot.put(" | ") 77.124 + end 77.125 + 77.126 + ui.link{ 77.127 + text = _"remove my support", 77.128 + module = "initiative", 77.129 + action = "remove_support", 77.130 + id = initiative.id, 77.131 + routing = { 77.132 + default = { 77.133 + mode = "redirect", 77.134 + module = "initiative", 77.135 + view = "show", 77.136 + id = initiative.id 77.137 + } 77.138 + } 77.139 + } 77.140 + 77.141 + end ) 77.142 + end 77.143 + end 77.144 + end 77.145 + 77.146 + 77.147 + ui.sectionRow( function () 77.148 + ui.container { 77.149 + attr = { class = "draft" }, 77.150 + content = function () 77.151 + slot.put ( initiative.current_draft:get_content ( "html" ) ) 77.152 + end 77.153 + } 77.154 + end ) 77.155 + 77.156 +end) 77.157 + 77.158 +ui.link { attr = { name = "suggestions" }, text = "" } 77.159 + 77.160 + 77.161 +ui.container { 77.162 + attr = { class = "section suggestions" }, 77.163 + content = function () 77.164 + 77.165 + if # ( initiative.suggestions ) > 0 then 77.166 + 77.167 + ui.sectionHead( function () 77.168 + ui.heading { 77.169 + level = 1, 77.170 + content = _("Suggestions for improvement (#{count})", { count = # ( initiative.suggestions ) } ) 77.171 + } 77.172 + ui.container { content = _"written and rated by the supportes of this initiative to improve the proposal and its reasons" } 77.173 + end ) 77.174 + 77.175 + for i, suggestion in ipairs(initiative.suggestions) do 77.176 + 77.177 + local opinion = Opinion:by_pk(app.session.member_id, suggestion.id) 77.178 + 77.179 + local class = "sectionRow suggestion" 77.180 + if suggestion.id == param.get("suggestion_id", atom.number) then 77.181 + class = class .. " highlighted" 77.182 + end 77.183 + if member and not initiative.issue.fully_frozen and not initiative.issue.closed and initiative.member_info.supported then 77.184 + class = class .. " rateable" 77.185 + end 77.186 + 77.187 + 77.188 + ui.tag { tag = "div", attr = { class = class, id = "s" .. suggestion.id }, content = function () 77.189 + 77.190 + if opinion then 77.191 + 77.192 + ui.container { attr = { class = "opinion"}, content = function() 77.193 + local class = "" 77.194 + local text = "" 77.195 + 77.196 + if opinion.degree == 2 then 77.197 + class = "must" 77.198 + text = _"must" 77.199 + elseif opinion.degree == 1 then 77.200 + class = "should" 77.201 + text = _"should" 77.202 + elseif opinion.degree == 0 then 77.203 + class = "neutral" 77.204 + text = _"neutral" 77.205 + elseif opinion.degree == -1 then 77.206 + class = "shouldnot" 77.207 + text = _"should not" 77.208 + elseif opinion.degree == -2 then 77.209 + class = "mustnot" 77.210 + text = _"must not" 77.211 + end 77.212 + 77.213 + ui.tag { 77.214 + attr = { class = class }, 77.215 + content = text 77.216 + } 77.217 + 77.218 + slot.put ( " " ) 77.219 + 77.220 + if 77.221 + (opinion.degree > 0 and not opinion.fulfilled) 77.222 + or (opinion.degree < 0 and opinion.fulfilled) 77.223 + then 77.224 + ui.tag{ content = _"but" } 77.225 + else 77.226 + ui.tag{ content = _"and" } 77.227 + end 77.228 + 77.229 + slot.put ( " " ) 77.230 + 77.231 + local class = "" 77.232 + local text = "" 77.233 + 77.234 + if opinion.fulfilled then 77.235 + class = "implemented" 77.236 + text = _"is implemented" 77.237 + else 77.238 + class = "notimplemented" 77.239 + text = _"is not implemented" 77.240 + end 77.241 + 77.242 + ui.tag { 77.243 + attr = { class = class }, 77.244 + content = text 77.245 + } 77.246 + 77.247 + if 77.248 + (opinion.degree > 0 and not opinion.fulfilled) 77.249 + or (opinion.degree < 0 and opinion.fulfilled) 77.250 + then 77.251 + if math.abs(opinion.degree) > 1 then 77.252 + slot.put(" !!") 77.253 + else 77.254 + slot.put(" !") 77.255 + end 77.256 + else 77.257 + slot.put(" ✓") 77.258 + end 77.259 + 77.260 + end } 77.261 + 77.262 + end 77.263 + 77.264 + 77.265 + ui.link { attr = { name = "s" .. suggestion.id }, text = "" } 77.266 + ui.heading { level = 2, 77.267 + attr = { class = "suggestionHead" }, 77.268 + content = format.string(suggestion.name, { 77.269 + truncate_at = 160, truncate_suffix = true 77.270 + }) } 77.271 + 77.272 + 77.273 + local plus2 = (suggestion.plus2_unfulfilled_count or 0) 77.274 + + (suggestion.plus2_fulfilled_count or 0) 77.275 + local plus1 = (suggestion.plus1_unfulfilled_count or 0) 77.276 + + (suggestion.plus1_fulfilled_count or 0) 77.277 + local minus1 = (suggestion.minus1_unfulfilled_count or 0) 77.278 + + (suggestion.minus1_fulfilled_count or 0) 77.279 + local minus2 = (suggestion.minus2_unfulfilled_count or 0) 77.280 + + (suggestion.minus2_fulfilled_count or 0) 77.281 + 77.282 + local with_opinion = plus2 + plus1 + minus1 + minus2 77.283 + 77.284 + local neutral = (suggestion.initiative.supporter_count or 0) 77.285 + - with_opinion 77.286 + 77.287 + local neutral2 = with_opinion 77.288 + - (suggestion.plus2_fulfilled_count or 0) 77.289 + - (suggestion.plus1_fulfilled_count or 0) 77.290 + - (suggestion.minus1_fulfilled_count or 0) 77.291 + - (suggestion.minus2_fulfilled_count or 0) 77.292 + 77.293 + ui.container { 77.294 + attr = { class = "suggestionInfo" }, 77.295 + content = function () 77.296 + 77.297 + if with_opinion > 0 then 77.298 + ui.container { attr = { class = "suggestion-rating" }, content = function () 77.299 + ui.tag { content = _"collective rating:" } 77.300 + slot.put(" ") 77.301 + ui.bargraph{ 77.302 + max_value = suggestion.initiative.supporter_count, 77.303 + width = 100, 77.304 + bars = { 77.305 + { color = "#0a0", value = plus2 }, 77.306 + { color = "#8a8", value = plus1 }, 77.307 + { color = "#eee", value = neutral }, 77.308 + { color = "#a88", value = minus1 }, 77.309 + { color = "#a00", value = minus2 }, 77.310 + } 77.311 + } 77.312 + slot.put(" | ") 77.313 + ui.tag { content = _"implemented:" } 77.314 + slot.put ( " " ) 77.315 + ui.bargraph{ 77.316 + max_value = with_opinion, 77.317 + width = 100, 77.318 + bars = { 77.319 + { color = "#0a0", value = suggestion.plus2_fulfilled_count }, 77.320 + { color = "#8a8", value = suggestion.plus1_fulfilled_count }, 77.321 + { color = "#eee", value = neutral2 }, 77.322 + { color = "#a88", value = suggestion.minus1_fulfilled_count }, 77.323 + { color = "#a00", value = suggestion.minus2_fulfilled_count }, 77.324 + } 77.325 + } 77.326 + end } 77.327 + end 77.328 + 77.329 + if app.session:has_access("authors_pseudonymous") then 77.330 + util.micro_avatar ( suggestion.author ) 77.331 + else 77.332 + slot.put("<br />") 77.333 + end 77.334 + 77.335 + ui.container { 77.336 + attr = { class = "suggestion-text" }, 77.337 + content = function () 77.338 + slot.put ( suggestion:get_content( "html" ) ) 77.339 + 77.340 + if direct_supporter then 77.341 + 77.342 + ui.container { 77.343 + attr = { class = "rating" }, 77.344 + content = function () 77.345 + 77.346 + if not opinion then 77.347 + opinion = {} 77.348 + end 77.349 + ui.form { 77.350 + module = "opinion", action = "update", params = { 77.351 + suggestion_id = suggestion.id 77.352 + }, 77.353 + routing = { default = { 77.354 + mode = "redirect", 77.355 + module = "initiative", view = "show", id = suggestion.initiative_id, 77.356 + params = { suggestion_id = suggestion.id }, 77.357 + anchor = "s" .. suggestion.id -- TODO webmcp 77.358 + } }, 77.359 + content = function () 77.360 + 77.361 + 77.362 + ui.heading { level = 3, content = _"Should the initiator implement this suggestion?" } 77.363 + ui.container { content = function () 77.364 + 77.365 + local active = opinion.degree == 2 77.366 + ui.tag { tag = "input", attr = { 77.367 + type = "radio", name = "degree", value = 2, 77.368 + id = "s" .. suggestion.id .. "_degree2", 77.369 + checked = active and "checked" or nil 77.370 + } } 77.371 + ui.tag { 77.372 + tag = "label", 77.373 + attr = { 77.374 + ["for"] = "s" .. suggestion.id .. "_degree2", 77.375 + class = active and "active-plus2" or nil, 77.376 + }, 77.377 + content = _"must" 77.378 + } 77.379 + 77.380 + local active = opinion.degree == 1 77.381 + ui.tag { tag = "input", attr = { 77.382 + type = "radio", name = "degree", value = 1, 77.383 + id = "s" .. suggestion.id .. "_degree1", 77.384 + checked = active and "checked" or nil 77.385 + } } 77.386 + ui.tag { 77.387 + tag = "label", 77.388 + attr = { 77.389 + ["for"] = "s" .. suggestion.id .. "_degree1", 77.390 + class = active and "active-plus1" or nil, 77.391 + }, 77.392 + content = _"should" 77.393 + } 77.394 + 77.395 + local active = not opinion.member_id 77.396 + ui.tag { tag = "input", attr = { 77.397 + type = "radio", name = "degree", value = 0, 77.398 + id = "s" .. suggestion.id .. "_degree0", 77.399 + checked = active and "checked" or nil 77.400 + } } 77.401 + ui.tag { 77.402 + tag = "label", 77.403 + attr = { 77.404 + ["for"] = "s" .. suggestion.id .. "_degree0", 77.405 + class = active and "active-neutral" or nil, 77.406 + }, 77.407 + content = _"neutral" 77.408 + } 77.409 + 77.410 + local active = opinion.degree == -1 77.411 + ui.tag { tag = "input", attr = { 77.412 + type = "radio", name = "degree", value = -1, 77.413 + id = "s" .. suggestion.id .. "_degree-1", 77.414 + checked = active and "checked" or nil 77.415 + } } 77.416 + ui.tag { 77.417 + tag = "label", 77.418 + attr = { 77.419 + ["for"] = "s" .. suggestion.id .. "_degree-1", 77.420 + class = active and "active-minus1" or nil, 77.421 + }, 77.422 + content = _"should not" 77.423 + } 77.424 + 77.425 + local active = opinion.degree == -2 77.426 + ui.tag { tag = "input", attr = { 77.427 + type = "radio", name = "degree", value = -2, 77.428 + id = "s" .. suggestion.id .. "_degree-2", 77.429 + checked = active and "checked" or nil 77.430 + } } 77.431 + ui.tag { 77.432 + tag = "label", 77.433 + attr = { 77.434 + ["for"] = "s" .. suggestion.id .. "_degree-2", 77.435 + class = active and "active-minus2" or nil, 77.436 + }, 77.437 + content = _"must not" 77.438 + } 77.439 + end } 77.440 + 77.441 + slot.put("<br />") 77.442 + 77.443 + ui.heading { level = 3, content = _"Did the initiator implement this suggestion?" } 77.444 + ui.container { content = function () 77.445 + local active = opinion.fulfilled == false 77.446 + ui.tag { tag = "input", attr = { 77.447 + type = "radio", name = "fulfilled", value = "false", 77.448 + id = "s" .. suggestion.id .. "_notfulfilled", 77.449 + checked = active and "checked" or nil 77.450 + } } 77.451 + ui.tag { 77.452 + tag = "label", 77.453 + attr = { 77.454 + ["for"] = "s" .. suggestion.id .. "_notfulfilled", 77.455 + class = active and "active-notfulfilled" or nil, 77.456 + }, 77.457 + content = _"No (not yet)" 77.458 + } 77.459 + 77.460 + local active = opinion.fulfilled 77.461 + ui.tag { tag = "input", attr = { 77.462 + type = "radio", name = "fulfilled", value = "true", 77.463 + id = "s" .. suggestion.id .. "_fulfilled", 77.464 + checked = active and "checked" or nil 77.465 + } } 77.466 + ui.tag { 77.467 + tag = "label", 77.468 + attr = { 77.469 + ["for"] = "s" .. suggestion.id .. "_fulfilled", 77.470 + class = active and "active-fulfilled" or nil, 77.471 + }, 77.472 + content = _"Yes, it's implemented" 77.473 + } 77.474 + end } 77.475 + slot.put("<br />") 77.476 + 77.477 + ui.tag{ 77.478 + tag = "input", 77.479 + attr = { 77.480 + type = "submit", 77.481 + class = "btn btn-default", 77.482 + value = _"publish my rating" 77.483 + }, 77.484 + content = "" 77.485 + } 77.486 + 77.487 + end 77.488 + } 77.489 + 77.490 + end -- if not issue,fully_frozen or closed 77.491 + } 77.492 + end 77.493 + 77.494 + local text = _"Read more" 77.495 + 77.496 + if direct_supporter then 77.497 + text = _"Show more and rate this" 77.498 + end 77.499 + 77.500 + ui.link { 77.501 + attr = { 77.502 + class = "suggestion-more", 77.503 + onclick = "$('#s" .. suggestion.id .. "').removeClass('folded').addClass('unfolded'); return false;" 77.504 + }, 77.505 + text = text 77.506 + } 77.507 + 77.508 + ui.link { 77.509 + attr = { 77.510 + class = "suggestion-less", 77.511 + onclick = "$('#s" .. suggestion.id .. "').addClass('folded').removeClass('unfolded'); return false;" 77.512 + }, 77.513 + text = _"Show less" 77.514 + } 77.515 + end 77.516 + } 77.517 + 77.518 + ui.script{ script = [[ 77.519 + var textEl = $('#s]] .. suggestion.id .. [[ .suggestion-text'); 77.520 + var height = textEl.height(); 77.521 + if (height > 150) $('#s]] .. suggestion.id .. [[').addClass('folded'); 77.522 + ]] } 77.523 + 77.524 + end 77.525 + } -- ui.paragraph 77.526 + 77.527 + 77.528 + 77.529 + end } -- ui.tag "li" 77.530 + 77.531 + end -- for i, suggestion 77.532 + 77.533 + else -- if #initiative.suggestions > 0 77.534 + 77.535 + local text 77.536 + if initiative.issue.closed then 77.537 + text = "No suggestions" 77.538 + else 77.539 + text = "No suggestions (yet)" 77.540 + end 77.541 + ui.sectionHead( function() 77.542 + ui.heading { level = 1, content = text } 77.543 + end) 77.544 + 77.545 + end -- if #initiative.suggestions > 0 77.546 + 77.547 + end 77.548 +}
78.1 --- a/app/main/interest/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 78.2 +++ b/app/main/interest/_action/update.lua Thu Jul 10 01:19:48 2014 +0200 78.3 @@ -4,6 +4,10 @@ 78.4 78.5 local issue = Issue:new_selector():add_where{ "id = ?", issue_id }:for_share():single_object_mode():exec() 78.6 78.7 +if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 78.8 + error("access denied") 78.9 +end 78.10 + 78.11 if issue.closed then 78.12 slot.put_into("error", _"This issue is already closed.") 78.13 return false 78.14 @@ -21,23 +25,17 @@ 78.15 if param.get("delete", atom.boolean) then 78.16 if interest then 78.17 interest:destroy() 78.18 - --slot.put_into("notice", _"Interest removed") 78.19 + slot.put_into("notice", _"Interest removed") 78.20 else 78.21 - --slot.put_into("notice", _"Interest not existent") 78.22 + slot.put_into("notice", _"Interest already removed") 78.23 end 78.24 return 78.25 end 78.26 78.27 -if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 78.28 - error("access denied") 78.29 -end 78.30 - 78.31 if not interest then 78.32 interest = Interest:new() 78.33 interest.issue_id = issue_id 78.34 interest.member_id = app.session.member_id 78.35 + interest:save() 78.36 + slot.put_into("notice", _"Interest updated") 78.37 end 78.38 - 78.39 -interest:save() 78.40 - 78.41 ---slot.put_into("notice", _"Interest updated")
79.1 --- a/app/main/interest/show_incoming.lua Thu Jul 10 01:02:43 2014 +0200 79.2 +++ b/app/main/interest/show_incoming.lua Thu Jul 10 01:19:48 2014 +0200 79.3 @@ -10,11 +10,25 @@ 79.4 :add_field{ "delegating_interest_snapshot.weight" } 79.5 79.6 execute.view{ 79.7 - module = "member", 79.8 - view = "_list", 79.9 - params = { 79.10 - members_selector = members_selector, 79.11 - issue = issue, 79.12 - trustee = member 79.13 + module = "issue", view = "_head", params = { 79.14 + issue = issue 79.15 } 79.16 -} 79.17 \ No newline at end of file 79.18 +} 79.19 + 79.20 +ui.section( function() 79.21 + 79.22 + ui.sectionHead( function() 79.23 + ui.heading{ level = 1, content = _("Incoming delegations for '#{member}'", { member = member.name }) } 79.24 + end) 79.25 + 79.26 + execute.view{ 79.27 + module = "member", 79.28 + view = "_list", 79.29 + params = { 79.30 + members_selector = members_selector, 79.31 + issue = issue, 79.32 + trustee = member 79.33 + } 79.34 + } 79.35 + 79.36 +end ) 79.37 \ No newline at end of file
80.1 --- a/app/main/issue/_details.lua Thu Jul 10 01:02:43 2014 +0200 80.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 80.3 @@ -1,58 +0,0 @@ 80.4 -local issue = param.get("issue", "table") 80.5 - 80.6 -local policy = issue.policy 80.7 -ui.form{ 80.8 - record = issue, 80.9 - readonly = true, 80.10 - attr = { class = "vertical" }, 80.11 - content = function() 80.12 - ui.field.text{ label = _"Population", name = "population" } 80.13 - ui.field.timestamp{ label = _"Created at", name = "created" } 80.14 - if policy.polling then 80.15 - ui.field.text{ label = _"Admission time", value = _"Implicitly admitted" } 80.16 - else 80.17 - ui.field.text{ label = _"Admission time", value = format.interval_text(issue.admission_time_text) } 80.18 - ui.field.text{ 80.19 - label = _"Issue quorum", 80.20 - value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) 80.21 - } 80.22 - if issue.population then 80.23 - ui.field.text{ 80.24 - label = _"Currently required", 80.25 - value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den) 80.26 - } 80.27 - end 80.28 - end 80.29 - if issue.accepted then 80.30 - ui.field.timestamp{ label = _"Accepted at", name = "accepted" } 80.31 - end 80.32 - ui.field.text{ label = _"Discussion time", value = format.interval_text(issue.discussion_time_text) } 80.33 - if issue.half_frozen then 80.34 - ui.field.timestamp{ label = _"Half frozen at", name = "half_frozen" } 80.35 - end 80.36 - ui.field.text{ label = _"Verification time", value = format.interval_text(issue.verification_time_text) } 80.37 - ui.field.text{ 80.38 - label = _"Initiative quorum", 80.39 - value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) 80.40 - } 80.41 - if issue.population then 80.42 - ui.field.text{ 80.43 - label = _"Currently required", 80.44 - value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)), 80.45 - } 80.46 - end 80.47 - if issue.fully_frozen then 80.48 - ui.field.timestamp{ label = _"Fully frozen at", name = "fully_frozen" } 80.49 - end 80.50 - ui.field.text{ label = _"Voting time", value = format.interval_text(issue.voting_time_text) } 80.51 - if issue.closed then 80.52 - ui.field.timestamp{ label = _"Closed", name = "closed" } 80.53 - end 80.54 - end 80.55 -} 80.56 -ui.form{ 80.57 - record = issue.policy, 80.58 - readonly = true, 80.59 - content = function() 80.60 - end 80.61 -}
81.1 --- a/app/main/issue/_filters.lua Thu Jul 10 01:02:43 2014 +0200 81.2 +++ b/app/main/issue/_filters.lua Thu Jul 10 01:19:48 2014 +0200 81.3 @@ -1,386 +1,326 @@ 81.4 -local member = param.get("member", "table") 81.5 -local for_member = param.get("for_member", "table") 81.6 -local state = param.get("state") 81.7 +local params = param.get_all_cgi() 81.8 + 81.9 local for_unit = param.get("for_unit", atom.boolean) 81.10 local for_area = param.get("for_area", atom.boolean) 81.11 - 81.12 local for_events = param.get("for_events", atom.boolean) 81.13 +local for_member = param.get("for_member", "table") 81.14 +local member = param.get("member", "table") 81.15 +local phase = params["phase"] 81.16 81.17 local filters = {} 81.18 81.19 -local filter = { name = "filter" } 81.20 - 81.21 -if state ~= "closed" then 81.22 - filter[#filter+1] = { 81.23 - name = "any", 81.24 - label = _"Any phase", 81.25 - selector_modifier = function(selector) end 81.26 - } 81.27 +local admission_order_field = "filter_issue_order.order_in_unit" 81.28 +if for_area then 81.29 + admission_order_field = "filter_issue_order.order_in_area" 81.30 end 81.31 81.32 -if not state then 81.33 +if not for_issue and not for_member then 81.34 + 81.35 + -- mode 81.36 + 81.37 + local filter = { class = "filter_mode", name = "mode" } 81.38 + 81.39 + filter[#filter+1] = { 81.40 + name = "issue", 81.41 + label = _"issue view", 81.42 + selector_modifier = function () end 81.43 + } 81.44 + 81.45 filter[#filter+1] = { 81.46 - name = "open", 81.47 - label = _"Open", 81.48 - selector_modifier = function(selector) 81.49 - if for_events then 81.50 - selector:add_where("event.state in ('admission', 'discussion', 'verification', 'voting')") 81.51 - else 81.52 - selector:add_where("issue.closed ISNULL") 81.53 + name = "timeline", 81.54 + label = _"timeline", 81.55 + selector_modifier = function ( selector ) 81.56 + selector:add_order_by ( "event.occurrence DESC" ) 81.57 + selector:add_order_by ( "id DESC" ) 81.58 + end 81.59 + } 81.60 + 81.61 + filters[#filters+1] = filter 81.62 + 81.63 + -- context 81.64 + 81.65 + local filter = { class = "filter_filter", name = "filter" } 81.66 + 81.67 + if member and not for_unit and not for_area then 81.68 + filter[#filter+1] = { 81.69 + name = "my_units", 81.70 + label = _"in my units", 81.71 + selector_modifier = function ( selector ) 81.72 + selector:join ( "area", "filter_area", "filter_area.id = issue.area_id" ) 81.73 + selector:join ( "privilege", "filter_privilege", { 81.74 + "filter_privilege.unit_id = filter_area.unit_id AND filter_privilege.member_id = ?", member.id 81.75 + }) 81.76 + end 81.77 + } 81.78 + end 81.79 + 81.80 + if member and not for_area then 81.81 + 81.82 + filter[#filter+1] = { 81.83 + name = "my_areas", 81.84 + label = _"in my areas", 81.85 + selector_modifier = function ( selector ) 81.86 + selector:join ( "membership", "filter_membership", { 81.87 + "filter_membership.area_id = issue.area_id AND filter_membership.member_id = ?", member.id 81.88 + }) 81.89 + end 81.90 + } 81.91 + end 81.92 + 81.93 + if member then 81.94 + filter[#filter+1] = { 81.95 + name = "my_issues", 81.96 + label = _"my issues", 81.97 + selector_modifier = function ( selector ) 81.98 + selector:left_join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", member.id }) 81.99 + --selector:left_join("direct_interest_snapshot", "filter_interest_s", { "filter_interest_s.issue_id = issue.id AND filter_interest_s.member_id = ? AND filter_interest_s.event = issue.latest_snapshot_event", member.id }) 81.100 + selector:left_join("delegating_interest_snapshot", "filter_d_interest_s", { "filter_d_interest_s.issue_id = issue.id AND filter_d_interest_s.member_id = ? AND filter_d_interest_s.event = issue.latest_snapshot_event", member.id }) 81.101 + end 81.102 + } 81.103 + end 81.104 + 81.105 + filter[#filter+1] = { 81.106 + name = "all", 81.107 + label = _"all issues", 81.108 + selector_modifier = function() end 81.109 + } 81.110 + 81.111 + filters[#filters+1] = filter 81.112 + 81.113 + -- phase 81.114 + 81.115 + local filter = { name = "phase" } 81.116 + 81.117 + filter[#filter+1] = { 81.118 + name = "all", 81.119 + label = _"in all phases", 81.120 + selector_modifier = function ( selector ) 81.121 + if not for_events then 81.122 + selector:left_join ( "issue_order_in_admission_state", "filter_issue_order", "filter_issue_order.id = issue.id" ) 81.123 + selector:add_order_by ( "issue.closed DESC NULLS FIRST" ) 81.124 + selector:add_order_by ( "issue.accepted ISNULL" ) 81.125 + selector:add_order_by ( "CASE WHEN issue.accepted ISNULL THEN NULL ELSE justify_interval(coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()) END" ) 81.126 + selector:add_order_by ( "CASE WHEN issue.accepted ISNULL THEN " .. admission_order_field .. " ELSE NULL END" ) 81.127 + selector:add_order_by ( "id" ) 81.128 end 81.129 end 81.130 } 81.131 -end 81.132 81.133 -if not state or state == "open" then 81.134 filter[#filter+1] = { 81.135 - name = "new", 81.136 - label = _"New", 81.137 - selector_modifier = function(selector) 81.138 - if for_events then 81.139 - selector:add_where("event.state = 'admission'") 81.140 - else 81.141 - selector:add_where("issue.accepted ISNULL AND issue.closed ISNULL") 81.142 + name = "admission", 81.143 + label = _"(1) Admission", 81.144 + selector_modifier = function ( selector ) 81.145 + selector:add_where { "issue.state = ?", "admission" } 81.146 + if not for_events then 81.147 + selector:left_join ( "issue_order_in_admission_state", "filter_issue_order", "filter_issue_order.id = issue.id" ) 81.148 + selector:add_order_by ( admission_order_field ) 81.149 + selector:add_order_by ( "id" ) 81.150 end 81.151 end 81.152 } 81.153 + 81.154 filter[#filter+1] = { 81.155 - name = "accepted", 81.156 - label = _"Discussion", 81.157 - selector_modifier = function(selector) 81.158 - if for_events then 81.159 - selector:add_where("event.state = 'discussion'") 81.160 - else 81.161 - selector:add_where("issue.accepted NOTNULL AND issue.half_frozen ISNULL AND issue.closed ISNULL") 81.162 + name = "discussion", 81.163 + label = _"(2) Discussion", 81.164 + selector_modifier = function ( selector ) 81.165 + selector:add_where { "issue.state = ?", "discussion" } 81.166 + if not for_events then 81.167 + selector:add_order_by ( "issue.accepted + issue.discussion_time - now()" ) 81.168 + selector:add_order_by ( "id" ) 81.169 end 81.170 end 81.171 } 81.172 + 81.173 filter[#filter+1] = { 81.174 - name = "half_frozen", 81.175 - label = _"Frozen", 81.176 - selector_modifier = function(selector) 81.177 - if for_events then 81.178 - selector:add_where("event.state = 'verification'") 81.179 - else 81.180 - selector:add_where("issue.half_frozen NOTNULL AND issue.fully_frozen ISNULL") 81.181 + name = "verification", 81.182 + label = _"(3) Verification", 81.183 + selector_modifier = function ( selector ) 81.184 + selector:add_where { "issue.state = ?", "verification" } 81.185 + if not for_events then 81.186 + selector:add_order_by ( "issue.half_frozen + issue.verification_time - now()" ) 81.187 + selector:add_order_by ( "id" ) 81.188 + end 81.189 + end 81.190 + } 81.191 + 81.192 + filter[#filter+1] = { 81.193 + name = "voting", 81.194 + label = _"(4) Voting", 81.195 + selector_modifier = function ( selector ) 81.196 + selector:add_where { "issue.state = ?", "voting" } 81.197 + if not for_events then 81.198 + selector:add_order_by ( "issue.fully_frozen + issue.voting_time - now()" ) 81.199 + selector:add_order_by ( "id" ) 81.200 end 81.201 end 81.202 } 81.203 - filter[#filter+1] = { 81.204 - name = "frozen", 81.205 - label = _"Voting", 81.206 - selector_modifier = function(selector) 81.207 - if for_events then 81.208 - selector:add_where("event.state = 'voting'") 81.209 - else 81.210 - selector:add_where("issue.fully_frozen NOTNULL AND issue.closed ISNULL") 81.211 - end 81.212 - filter_voting = true 81.213 - end 81.214 - } 81.215 -end 81.216 81.217 -if not state then 81.218 filter[#filter+1] = { 81.219 - name = "finished", 81.220 - label = _"Finished", 81.221 - selector_modifier = function(selector) 81.222 - if for_events then 81.223 - selector:add_where("event.state IN ('finished_with_winner', 'finished_without_winner')") 81.224 - else 81.225 - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen NOTNULL") 81.226 - end 81.227 - end 81.228 - } 81.229 - filter[#filter+1] = { 81.230 - name = "canceled", 81.231 - label = _"Canceled", 81.232 - selector_modifier = function(selector) 81.233 - 81.234 - if for_events then 81.235 - selector:add_where("event.state IN ('canceled_revoked_before_accepted', 'canceled_issue_not_accepted', 'canceled_after_revocation_during_discussion', 'canceled_after_revocation_during_verification')") 81.236 - else 81.237 - selector:add_where("issue.closed NOTNULL AND issue.fully_frozen ISNULL") 81.238 + name = "closed", 81.239 + label = _"(5) Result", 81.240 + selector_modifier = function ( selector ) 81.241 + if not for_events then 81.242 + selector:add_where ( "issue.closed NOTNULL" ) 81.243 + selector:add_order_by ( "issue.closed DESC" ) 81.244 + selector:add_order_by ( "id" ) 81.245 end 81.246 end 81.247 } 81.248 -end 81.249 + 81.250 + filters[#filters+1] = filter 81.251 + 81.252 + -- my issues 81.253 + 81.254 + if params["filter"] == "my_issues" then 81.255 + 81.256 + local delegation = params["delegation"] 81.257 81.258 -if state == "closed" then 81.259 - filter[#filter+1] = { 81.260 - name = "any", 81.261 - label = _"Any state", 81.262 - selector_modifier = function(selector) end 81.263 - } 81.264 + local filter = { class = "filter_interest subfilter", name = "interest" } 81.265 + 81.266 + filter[#filter+1] = { 81.267 + name = "all", 81.268 + label = _"interested directly or via delegation", 81.269 + selector_modifier = function ( selector ) 81.270 + selector:add_where ( "filter_interest.issue_id NOTNULL OR filter_d_interest_s.issue_id NOTNULL" ) 81.271 + end 81.272 + } 81.273 + 81.274 + filter[#filter+1] = { 81.275 + name = "direct", 81.276 + label = _"direct interest", 81.277 + selector_modifier = function ( selector ) 81.278 + selector:add_where ( "filter_interest.issue_id NOTNULL" ) 81.279 + end 81.280 + } 81.281 81.282 - filter[#filter+1] = { 81.283 - name = "finished", 81.284 - label = _"Finished", 81.285 - selector_modifier = function(selector) 81.286 - if for_events then 81.287 - selector:add_where("event.state IN ('finished_with_winner', 'finished_without_winner')") 81.288 - else 81.289 - selector:add_where("issue.state IN ('finished_with_winner', 'finished_without_winner')") 81.290 + filter[#filter+1] = { 81.291 + name = "via_delegation", 81.292 + label = _"interest via delegation", 81.293 + selector_modifier = function ( selector ) 81.294 + selector:add_where ( "filter_d_interest_s.issue_id NOTNULL" ) 81.295 + end 81.296 + } 81.297 + 81.298 + filter[#filter+1] = { 81.299 + name = "initiated", 81.300 + label = _"initiated by me", 81.301 + selector_modifier = function ( selector ) 81.302 + selector:add_where ( "filter_interest.issue_id NOTNULL" ) 81.303 end 81.304 - end 81.305 - } 81.306 - filter[#filter+1] = { 81.307 - name = "finished_with_winner", 81.308 - label = _"with winner", 81.309 - selector_modifier = function(selector) 81.310 - if for_events then 81.311 - selector:add_where("event.state = 'finished_with_winner'") 81.312 - else 81.313 - selector:add_where("issue.state = 'finished_with_winner'") 81.314 + } 81.315 + 81.316 + filters[#filters+1] = filter 81.317 + 81.318 + end 81.319 + 81.320 + -- voting 81.321 + 81.322 + if phase == "voting" and member then 81.323 + 81.324 + local filter = { class = "subfilter", name = "voted" } 81.325 + 81.326 + filter[#filter+1] = { 81.327 + name = "all", 81.328 + label = _"voted and not voted by me", 81.329 + selector_modifier = function(selector) end 81.330 + } 81.331 + 81.332 + filter[#filter+1] = { 81.333 + name = "voted", 81.334 + label = _"voted by me", 81.335 + selector_modifier = function(selector) 81.336 + selector:join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id }) 81.337 end 81.338 - end 81.339 - } 81.340 - filter[#filter+1] = { 81.341 - name = "finished_without_winner", 81.342 - label = _"without winner", 81.343 - selector_modifier = function(selector) 81.344 - if for_events then 81.345 - selector:add_where("event.state = 'finished_without_winner'") 81.346 - else 81.347 - selector:add_where("issue.state = 'finished_without_winner'") 81.348 + } 81.349 + 81.350 + filter[#filter+1] = { 81.351 + name = "not_voted", 81.352 + label = _"not voted by me", 81.353 + selector_modifier = function(selector) 81.354 + selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id }) 81.355 + selector:add_where("filter_direct_voter.issue_id ISNULL") 81.356 end 81.357 - end 81.358 - } 81.359 - filter[#filter+1] = { 81.360 - name = "canceled", 81.361 - label = _"Canceled", 81.362 - selector_modifier = function(selector) 81.363 - if for_events then 81.364 - selector:add_where("event.state NOT IN ('finished_with_winner', 'finished_without_winner')") 81.365 - else 81.366 - selector:add_where("issue.state NOT IN ('finished_with_winner', 'finished_without_winner')") 81.367 + } 81.368 + filters[#filters+1] = filter 81.369 + 81.370 + 81.371 + end 81.372 + 81.373 + -- closed 81.374 + 81.375 + if phase == "closed" then 81.376 + 81.377 + local filter = { class = "subfilter", name = "closed" } 81.378 + 81.379 + filter[#filter+1] = { 81.380 + name = "finished", 81.381 + label = _"finished", 81.382 + selector_modifier = function ( selector ) 81.383 + selector:add_where ( "issue.state::text like 'finished_%'" ) 81.384 + end 81.385 + } 81.386 + 81.387 + filter[#filter+1] = { 81.388 + name = "canceled", 81.389 + label = _"canceled", 81.390 + selector_modifier = function ( selector ) 81.391 + selector:add_where ( "issue.closed NOTNULL AND NOT issue.state::text like 'finished_%' AND issue.accepted NOTNULL" ) 81.392 end 81.393 - end 81.394 - } 81.395 -end 81.396 + } 81.397 + 81.398 + filter[#filter+1] = { 81.399 + name = "not_accepted", 81.400 + label = _"not admitted", 81.401 + selector_modifier = function ( selector ) 81.402 + selector:add_where ( "issue.closed NOTNULL AND issue.accepted ISNULL" ) 81.403 + end 81.404 + } 81.405 81.406 -filters[#filters+1] = filter 81.407 - 81.408 + if member then 81.409 + filter[#filter+1] = { 81.410 + name = "voted", 81.411 + label = _"voted by me", 81.412 + selector_modifier = function(selector) 81.413 + selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id }) 81.414 + selector:left_join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id }) 81.415 + selector:add_where("filter_direct_voter.issue_id NOTNULL or filter_delegating_voter.issue_id NOTNULL") 81.416 + end 81.417 + } 81.418 81.419 -if member then 81.420 - local filter = { 81.421 - name = "filter_interest", 81.422 - } 81.423 - if not for_member then 81.424 - if not for_unit and not for_area then 81.425 + filter[#filter+1] = { 81.426 + name = "voted_direct", 81.427 + label = _"voted directly by me", 81.428 + selector_modifier = function(selector) 81.429 + selector:join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id }) 81.430 + end 81.431 + } 81.432 + 81.433 filter[#filter+1] = { 81.434 - name = "any", 81.435 - label = _"All units", 81.436 - selector_modifier = function() end 81.437 + name = "voted_via_delegation", 81.438 + label = _"voted via delegation", 81.439 + selector_modifier = function(selector) 81.440 + selector:join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id }) 81.441 + end 81.442 } 81.443 + 81.444 filter[#filter+1] = { 81.445 - name = "unit", 81.446 - label = _"My units", 81.447 + name = "not_voted", 81.448 + label = _"not voted by me", 81.449 selector_modifier = function(selector) 81.450 - selector:join("area", nil, "area.id = issue.area_id") 81.451 - selector:join("privilege", nil, { "privilege.unit_id = area.unit_id AND privilege.member_id = ? AND privilege.voting_right", member.id }) 81.452 + selector:left_join("direct_voter", "filter_direct_voter", { "filter_direct_voter.issue_id = issue.id AND filter_direct_voter.member_id = ?", member.id }) 81.453 + selector:left_join("delegating_voter", "filter_delegating_voter", { "filter_delegating_voter.issue_id = issue.id AND filter_delegating_voter.member_id = ?", member.id }) 81.454 + selector:add_where("filter_direct_voter.issue_id ISNULL AND filter_delegating_voter.issue_id ISNULL") 81.455 end 81.456 } 81.457 end 81.458 - if for_unit and not for_area then 81.459 - filter[#filter+1] = { 81.460 - name = "any", 81.461 - label = _"All areas", 81.462 - selector_modifier = function() end 81.463 - } 81.464 - end 81.465 - if not for_area then 81.466 - filter[#filter+1] = { 81.467 - name = "area", 81.468 - label = _"My areas", 81.469 - selector_modifier = function(selector) 81.470 - selector:join("membership", nil, { "membership.area_id = issue.area_id AND membership.member_id = ?", member.id }) 81.471 - end 81.472 - } 81.473 - end 81.474 - if for_area then 81.475 - filter[#filter+1] = { 81.476 - name = "any", 81.477 - label = _"All issues", 81.478 - selector_modifier = function() end 81.479 - } 81.480 - end 81.481 - end 81.482 - filter[#filter+1] = { 81.483 - name = "issue", 81.484 - label = _"Interested", 81.485 - selector_modifier = function() end 81.486 - } 81.487 - filter[#filter+1] = { 81.488 - name = "initiated", 81.489 - label = _"Initiated", 81.490 - selector_modifier = function(selector) 81.491 - selector:add_where({ "EXISTS (SELECT 1 FROM initiative JOIN initiator ON initiator.initiative_id = initiative.id AND initiator.member_id = ? AND initiator.accepted WHERE initiative.issue_id = issue.id)", member.id }) 81.492 - end 81.493 - } 81.494 - filter[#filter+1] = { 81.495 - name = "supported", 81.496 - label = _"Supported", 81.497 - selector_modifier = function() end 81.498 - } 81.499 - filter[#filter+1] = { 81.500 - name = "potentially_supported", 81.501 - label = _"Potentially supported", 81.502 - selector_modifier = function() end 81.503 - } 81.504 - if state == 'closed' or (for_events) then 81.505 - filter[#filter+1] = { 81.506 - name = "voted", 81.507 - label = _"Voted", 81.508 - selector_modifier = function() end 81.509 - } 81.510 + 81.511 + filters[#filters+1] = filter 81.512 + 81.513 + 81.514 end 81.515 81.516 - filters[#filters+1] = filter 81.517 + 81.518 end 81.519 81.520 81.521 - 81.522 -if app.session.member then 81.523 - 81.524 - local filter_interest = param.get_all_cgi()["filter_interest"] 81.525 - 81.526 - if filter_interest ~= "any" and filter_interest ~= nil and ( 81.527 - filter_interest == "issue" or filter_interest == "supported" or filter_interest == "potentially_supported" or 81.528 - (filter_interest == 'voted' and state ~= 'open') 81.529 - ) then 81.530 - 81.531 - local function add_default_joins(selector) 81.532 - selector:left_join("interest", "filter_interest", { "filter_interest.issue_id = issue.id AND filter_interest.member_id = ? ", member.id }) 81.533 - selector:left_join("direct_interest_snapshot", "filter_interest_s", { "filter_interest_s.issue_id = issue.id AND filter_interest_s.member_id = ? AND filter_interest_s.event = issue.latest_snapshot_event", member.id }) 81.534 - selector:left_join("delegating_interest_snapshot", "filter_d_interest_s", { "filter_d_interest_s.issue_id = issue.id AND filter_d_interest_s.member_id = ? AND filter_d_interest_s.event = issue.latest_snapshot_event", member.id }) 81.535 - end 81.536 - 81.537 - filters[#filters+1] = { 81.538 - name = "filter_delegation", 81.539 - { 81.540 - name = "any", 81.541 - label = _"Direct and by delegation", 81.542 - selector_modifier = function(selector) 81.543 - add_default_joins(selector) 81.544 - selector:add_where("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN filter_interest.member_id NOTNULL ELSE filter_interest_s.member_id NOTNULL END OR filter_d_interest_s.member_id NOTNULL") 81.545 - if filter_interest == "supported" then 81.546 - selector:add_where({ 81.547 - "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " .. 81.548 - "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id ISNULL) " .. 81.549 - "ELSE " .. 81.550 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND direct_supporter_snapshot.satisfied) " .. 81.551 - "END OR EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND direct_supporter_snapshot.satisfied)", member.id, member.id, member.id }) 81.552 - 81.553 - elseif filter_interest == "potentially_supported" then 81.554 - selector:add_where({ 81.555 - "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " .. 81.556 - "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id NOTNULL) " .. 81.557 - "ELSE " .. 81.558 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND NOT direct_supporter_snapshot.satisfied) " .. 81.559 - "END OR EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND NOT direct_supporter_snapshot.satisfied)", member.id, member.id, member.id }) 81.560 - 81.561 - elseif filter_interest == "voted" then 81.562 - selector:add_where({ "EXISTS(SELECT 1 FROM direct_voter WHERE direct_voter.issue_id = issue.id AND direct_voter.member_id = ?) OR (issue.closed NOTNULL AND EXISTS(SELECT 1 FROM delegating_voter WHERE delegating_voter.issue_id = issue.id AND delegating_voter.member_id = ?)) ", member.id, member.id }) 81.563 - 81.564 - end 81.565 - 81.566 - end 81.567 - }, 81.568 - { 81.569 - name = "direct", 81.570 - label = _"Direct", 81.571 - selector_modifier = function(selector) 81.572 - add_default_joins(selector) 81.573 - selector:add_where("CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN filter_interest.member_id NOTNULL ELSE filter_interest_s.member_id NOTNULL END") 81.574 - 81.575 - if filter_interest == "supported" then 81.576 - selector:add_where({ 81.577 - "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " .. 81.578 - "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id ISNULL) " .. 81.579 - "ELSE " .. 81.580 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND direct_supporter_snapshot.satisfied) " .. 81.581 - "END", member.id, member.id }) 81.582 - 81.583 - elseif filter_interest == "potentially_supported" then 81.584 - selector:add_where({ 81.585 - "CASE WHEN issue.fully_frozen ISNULL AND issue.closed ISNULL THEN " .. 81.586 - "EXISTS(SELECT 1 FROM initiative JOIN supporter ON supporter.initiative_id = initiative.id AND supporter.member_id = ? LEFT JOIN critical_opinion ON critical_opinion.initiative_id = initiative.id AND critical_opinion.member_id = supporter.member_id WHERE initiative.issue_id = issue.id AND critical_opinion.member_id NOTNULL) " .. 81.587 - "ELSE " .. 81.588 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = ? AND NOT direct_supporter_snapshot.satisfied) " .. 81.589 - "END", member.id, member.id }) 81.590 - elseif filter_interest == "voted" then 81.591 - selector:add_where({ "EXISTS(SELECT 1 FROM direct_voter WHERE direct_voter.issue_id = issue.id AND direct_voter.member_id = ?) ", member.id }) 81.592 - 81.593 - end 81.594 - end 81.595 - }, 81.596 - { 81.597 - name = "delegated", 81.598 - label = _"By delegation", 81.599 - selector_modifier = function(selector) 81.600 - add_default_joins(selector) 81.601 - selector:add_where("filter_d_interest_s.member_id NOTNULL AND filter_interest.member_id ISNULL") 81.602 - 81.603 - if filter_interest == "supported" then 81.604 - selector:add_where({ 81.605 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND direct_supporter_snapshot.satisfied)", member.id }) 81.606 - 81.607 - elseif filter_interest == "potentially_supported" then 81.608 - selector:add_where({ 81.609 - "EXISTS(SELECT 1 FROM direct_supporter_snapshot WHERE direct_supporter_snapshot.event = issue.latest_snapshot_event AND direct_supporter_snapshot.issue_id = issue.id AND direct_supporter_snapshot.member_id = filter_d_interest_s.delegate_member_ids[array_upper(filter_d_interest_s.delegate_member_ids,1)] AND NOT direct_supporter_snapshot.satisfied)", member.id }) 81.610 - elseif filter_interest == "voted" then 81.611 - selector:add_where({ "issue.closed NOTNULL AND EXISTS(SELECT 1 FROM delegating_voter WHERE delegating_voter.issue_id = issue.id AND delegating_voter.member_id = ?) ", member.id }) 81.612 - 81.613 - end 81.614 - end 81.615 - } 81.616 - } 81.617 - end 81.618 - 81.619 -end 81.620 - 81.621 -if state == 'open' and app.session.member and member.id == app.session.member_id and (param.get_all_cgi()["filter"] == "frozen") then 81.622 - filters[#filters+1] = { 81.623 - name = "filter_voting", 81.624 - { 81.625 - name = "any", 81.626 - label = _"Any", 81.627 - selector_modifier = function() end 81.628 - }, 81.629 - { 81.630 - name = "not_voted", 81.631 - label = _"Not voted", 81.632 - selector_modifier = function(selector) 81.633 - selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", member.id }) 81.634 - selector:add_where("direct_voter.member_id ISNULL") 81.635 - selector:left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", member.id }) 81.636 - selector:add_where("non_voter.member_id ISNULL") 81.637 - end 81.638 - }, 81.639 - { 81.640 - name = "voted", 81.641 - label = _"Voted", 81.642 - selector_modifier = function(selector) 81.643 - selector:join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", member.id }) 81.644 - end 81.645 - }, 81.646 - } 81.647 -end 81.648 - 81.649 - 81.650 - 81.651 - 81.652 -function filters:get_filter(group, name) 81.653 - for i,grp in ipairs(self) do 81.654 - if grp.name == group then 81.655 - for i,entry in ipairs(grp) do 81.656 - if entry.name == name then 81.657 - return entry 81.658 - end 81.659 - end 81.660 - end 81.661 - end 81.662 -end 81.663 - 81.664 -return filters 81.665 \ No newline at end of file 81.666 +return filters
82.1 --- a/app/main/issue/_head.lua Thu Jul 10 01:02:43 2014 +0200 82.2 +++ b/app/main/issue/_head.lua Thu Jul 10 01:19:48 2014 +0200 82.3 @@ -1,3 +1,74 @@ 82.4 local issue = param.get("issue", "table") 82.5 +local initiative = param.get("initiative", "table") 82.6 + 82.7 +local member = param.get ( "member", "table" ) 82.8 + 82.9 + 82.10 +ui.title ( function () 82.11 + 82.12 + ui.tag { 82.13 + attr = { class = "unit" }, 82.14 + content = function() 82.15 + ui.link { 82.16 + content = function() 82.17 + ui.tag{ attr = { class = "name" }, content = issue.area.unit.name } 82.18 + end, 82.19 + module = "unit", view = "show", 82.20 + id = issue.area.unit.id 82.21 + } 82.22 + end 82.23 + } 82.24 + ui.tag { attr = { class = "spacer" }, content = function() 82.25 + slot.put ( " » " ) 82.26 + end } 82.27 + 82.28 + ui.tag { 82.29 + attr = { class = "area" }, 82.30 + content = function() 82.31 + ui.link { 82.32 + content = function() 82.33 + ui.tag{ attr = { class = "name" }, content = issue.area.name } 82.34 + end, 82.35 + module = "area", view = "show", 82.36 + id = issue.area.id 82.37 + } 82.38 + end 82.39 + } 82.40 82.41 -execute.view{ module = "area", view = "_head", params = { area = issue.area } } 82.42 + ui.tag { attr = { class = "spacer" }, content = function() 82.43 + slot.put ( " » " ) 82.44 + end } 82.45 + 82.46 + ui.tag { 82.47 + attr = { class = "issue" }, 82.48 + content = function() 82.49 + -- issue link 82.50 + ui.link { 82.51 + text = _("#{policy_name} ##{issue_id}", { 82.52 + policy_name = issue.policy.name, 82.53 + issue_id = issue.id 82.54 + } ), 82.55 + module = "issue", view = "show", 82.56 + id = issue.id 82.57 + } 82.58 + 82.59 + slot.put ( " " ) 82.60 + 82.61 + if member then 82.62 + execute.view { 82.63 + module = "delegation", view = "_info", params = { 82.64 + issue = issue, member = member, for_title = true 82.65 + } 82.66 + } 82.67 + end 82.68 + end 82.69 + } 82.70 + 82.71 + if initiative then 82.72 + ui.tag{ 82.73 + attr = { class = "initiative" }, 82.74 + content = initiative.display_name 82.75 + } 82.76 + end 82.77 + 82.78 +end ) -- ui.title
83.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 83.2 +++ b/app/main/issue/_head2.lua Thu Jul 10 01:19:48 2014 +0200 83.3 @@ -0,0 +1,96 @@ 83.4 +local issue = param.get("issue", "table") 83.5 +local for_history = param.get("for_history", atom.boolean) 83.6 + 83.7 +ui.sectionHead( "issueInfo", function () 83.8 + ui.container { attr = { class = "left" }, content = function() 83.9 + ui.heading { level = 1, content = issue.name } 83.10 + end } 83.11 + if app.session.member then 83.12 + ui.container { attr = { class = "right" }, content = function () 83.13 + if issue.fully_frozen then 83.14 + if issue.member_info.direct_voted then 83.15 + ui.image { attr = { class = "icon48 right" }, static = "icons/48/voted_ok.png" } 83.16 + ui.tag { content = _"You have voted" } 83.17 + slot.put(" ") 83.18 + if not issue.closed then 83.19 + slot.put("<br />") 83.20 + ui.link { 83.21 + module = "vote", view = "list", 83.22 + params = { issue_id = issue.id }, 83.23 + text = _"change vote" 83.24 + } 83.25 + else 83.26 + ui.link { 83.27 + module = "vote", view = "list", 83.28 + params = { issue_id = issue.id }, 83.29 + text = _"show vote" 83.30 + } 83.31 + end 83.32 + slot.put(" ") 83.33 + elseif active_trustee_id then 83.34 + ui.tag { content = _"You have voted via delegation" } 83.35 + ui.link { 83.36 + content = _"Show voting ballot", 83.37 + module = "vote", view = "list", params = { 83.38 + issue_id = issue.id, member_id = active_trustee_id 83.39 + } 83.40 + } 83.41 + elseif not issue.closed then 83.42 + ui.link { 83.43 + attr = { class = "btn btn-default" }, 83.44 + module = "vote", view = "list", 83.45 + params = { issue_id = issue.id }, 83.46 + text = _"vote now" 83.47 + } 83.48 + end 83.49 + elseif not issue.closed then 83.50 + if issue.member_info.own_participation then 83.51 + ui.image { attr = { class = "icon48 right" }, static = "icons/48/eye.png" } 83.52 + ui.tag{ content = _"You are interested in this issue" } 83.53 + slot.put("<br />") 83.54 + ui.link { 83.55 + module = "interest", action = "update", 83.56 + params = { issue_id = issue.id, delete = true }, 83.57 + routing = { default = { 83.58 + mode = "redirect", module = "issue", view = "show", id = issue.id 83.59 + } }, 83.60 + text = _"remove my interest" 83.61 + } 83.62 + else 83.63 + ui.link { 83.64 + attr = { class = "btn btn-default" }, 83.65 + module = "interest", action = "update", 83.66 + params = { issue_id = issue.id }, 83.67 + routing = { default = { 83.68 + mode = "redirect", module = "issue", view = "show", id = issue.id 83.69 + } }, 83.70 + text = _"add my interest" 83.71 + } 83.72 + end 83.73 + end 83.74 + end } 83.75 + end 83.76 +end) 83.77 + 83.78 +ui.container { 83.79 + attr = { class = "ui_filter", style="clear: left; margin-top: 4px;" }, 83.80 + content = function () 83.81 + ui.container { 83.82 + attr = { class = "ui_filter_head" }, 83.83 + content = function () 83.84 + 83.85 + ui.link{ 83.86 + attr = { class = not for_history and "active" or nil }, 83.87 + text = _"Initiatives", 83.88 + module = "issue", view = "show", id = issue.id 83.89 + } 83.90 + slot.put(" ") 83.91 + ui.link{ 83.92 + attr = { class = for_history and "active" or nil }, 83.93 + text = _"History", 83.94 + module = "issue", view = "history", id = issue.id 83.95 + } 83.96 + end 83.97 + } 83.98 + end 83.99 +}
84.1 --- a/app/main/issue/_list.lua Thu Jul 10 01:02:43 2014 +0200 84.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 84.3 @@ -1,57 +0,0 @@ 84.4 -local issues_selector = param.get("issues_selector", "table") 84.5 -local member = param.get("for_member", "table") or app.session.member 84.6 -local for_member = param.get("for_member", "table") 84.7 -local for_state = param.get("for_state") 84.8 -local for_unit = param.get("for_unit", atom.boolean) 84.9 -local for_area = param.get("for_area", atom.boolean) 84.10 - 84.11 - 84.12 -if for_state == "open" then 84.13 - issues_selector:add_where("issue.closed ISNULL") 84.14 -elseif for_state == "closed" then 84.15 - issues_selector:add_where("issue.closed NOTNULL") 84.16 -end 84.17 - 84.18 -ui.add_partial_param_names{ 84.19 - "filter", 84.20 - "filter_open", 84.21 - "filter_voting", 84.22 - "filter_interest", 84.23 - "issue_list" 84.24 -} 84.25 - 84.26 -local filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = { 84.27 - member = member, for_member = for_member, state = for_state, for_unit = for_unit, for_area = for_area 84.28 -}} 84.29 - 84.30 -filters.content = function() 84.31 - ui.paginate{ 84.32 - per_page = tonumber(param.get("per_page") or 25), 84.33 - selector = issues_selector, 84.34 - content = function() 84.35 - local highlight_string = param.get("highlight_string", "string") 84.36 - local issues = issues_selector:exec() 84.37 - issues:load_everything_for_member_id(member and member.id or nil) 84.38 - 84.39 - ui.container{ attr = { class = "issues" }, content = function() 84.40 - 84.41 - for i, issue in ipairs(issues) do 84.42 - 84.43 - execute.view{ module = "issue", view = "_show", params = { 84.44 - issue = issue, for_listing = true, for_member = for_member 84.45 - } } 84.46 - 84.47 - end 84.48 - end } 84.49 - end 84.50 - } 84.51 -end 84.52 - 84.53 -filters.opened = true 84.54 -filters.selector = issues_selector 84.55 - 84.56 -if param.get("no_filter", atom.boolean) then 84.57 - filters.content() 84.58 -else 84.59 - ui.filters(filters) 84.60 -end
85.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 85.2 +++ b/app/main/issue/_list2.lua Thu Jul 10 01:19:48 2014 +0200 85.3 @@ -0,0 +1,373 @@ 85.4 +local for_member = param.get ( "for_member", "table" ) 85.5 +local for_unit = param.get ( "for_unit", "table" ) 85.6 +local for_area = param.get ( "for_area", "table" ) 85.7 +local for_issue = param.get ( "for_issue", "table" ) 85.8 +local for_initiative = param.get ( "for_initiative", "table" ) 85.9 +local for_sidebar = param.get("for_sidebar", atom.boolean) 85.10 +local no_filter = param.get ( "no_filter", atom.boolean ) 85.11 +local search = param.get ( "search" ) 85.12 + 85.13 +local limit = 25 85.14 + 85.15 +local mode = param.get_all_cgi()["mode"] or "issue" 85.16 + 85.17 +if for_initiative or for_issue or for_member then 85.18 + mode = "timeline" 85.19 +end 85.20 + 85.21 +local selector 85.22 + 85.23 +if search then 85.24 + 85.25 + selector = Issue:get_search_selector(search) 85.26 + 85.27 + 85.28 +elseif mode == "timeline" then 85.29 + 85.30 + local event_max_id = param.get_all_cgi()["event_max_id"] 85.31 + 85.32 + selector = Event:new_selector() 85.33 + :add_order_by("event.id DESC") 85.34 + :join("issue", nil, "issue.id = event.issue_id") 85.35 + :add_field("now() - event.occurrence", "time_ago") 85.36 + :limit(limit + 1) 85.37 + 85.38 + if event_max_id then 85.39 + selector:add_where{ "event.id < ?", event_max_id } 85.40 + end 85.41 + 85.42 + if for_member then 85.43 + selector:add_where{ "event.member_id = ?", for_member.id } 85.44 + end 85.45 + 85.46 + if for_initiative then 85.47 + selector:add_where{ "event.initiative_id = ?", for_initiative.id } 85.48 + end 85.49 + 85.50 + 85.51 +elseif mode == "issue" then 85.52 + 85.53 + selector = Issue:new_selector() 85.54 + 85.55 +end 85.56 + 85.57 +if for_unit then 85.58 + selector:join("area", nil, "area.id = issue.area_id") 85.59 + selector:add_where{ "area.unit_id = ?", for_unit.id } 85.60 +elseif for_area then 85.61 + selector:add_where{ "issue.area_id = ?", for_area.id } 85.62 +elseif for_issue then 85.63 + selector:add_where{ "issue.id = ?", for_issue.id } 85.64 +end 85.65 + 85.66 +if not search and app.session.member_id then 85.67 + selector 85.68 + :left_join("interest", "_interest", { 85.69 + "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id 85.70 + } ) 85.71 + :add_field("(_interest.member_id NOTNULL)", "is_interested") 85.72 + :left_join("delegating_interest_snapshot", "_delegating_interest", { [[ 85.73 + _delegating_interest.issue_id = issue.id AND 85.74 + _delegating_interest.member_id = ? AND 85.75 + _delegating_interest.event = issue.latest_snapshot_event 85.76 + ]], app.session.member.id } ) 85.77 + :add_field("_delegating_interest.delegate_member_ids[1]", "is_interested_by_delegation_to_member_id") 85.78 + :add_field("_delegating_interest.delegate_member_ids[array_upper(_delegating_interest.delegate_member_ids, 1)]", "is_interested_via_member_id") 85.79 + :add_field("array_length(_delegating_interest.delegate_member_ids, 1)", "delegation_chain_length") 85.80 +end 85.81 + 85.82 +function doit() 85.83 + 85.84 + local last_event_id 85.85 + 85.86 + local items = selector:exec() 85.87 + 85.88 + if #items < 1 then 85.89 + ui.section( function() 85.90 + ui.sectionRow( function() 85.91 + ui.heading{ level = 2, content = _"No results for this selection" } 85.92 + end ) 85.93 + end ) 85.94 + return 85.95 + end 85.96 + 85.97 + local row_class = "sectionRow" 85.98 + if for_sidebar then 85.99 + row_class = "sidebarRow" 85.100 + end 85.101 + 85.102 + if mode == "timeline" then 85.103 + local issues = items:load ( "issue" ) 85.104 + local initiative = items:load ( "initiative" ) 85.105 + items:load ( "suggestion" ) 85.106 + items:load ( "member" ) 85.107 + issues:load_everything_for_member_id ( app.session.member_id ) 85.108 + initiative:load_everything_for_member_id ( app.session.member_id ) 85.109 + elseif mode == "issue" then 85.110 + items:load_everything_for_member_id ( app.session.member_id ) 85.111 + end 85.112 + 85.113 + local class = "section" 85.114 + if mode == "timeline" then 85.115 + class = class .. " events" 85.116 + elseif mode == "issue" then 85.117 + class = class .. " issues" 85.118 + end 85.119 + 85.120 + ui.container{ attr = { class = class }, content = function() 85.121 + 85.122 + local last_event_date 85.123 + for i, item in ipairs(items) do 85.124 + local event 85.125 + local issue 85.126 + if mode == "timeline" then 85.127 + event = item 85.128 + issue = item.issue 85.129 + elseif mode == "issue" then 85.130 + event = {} 85.131 + issue = item 85.132 + end 85.133 + 85.134 + last_event_id = event.id 85.135 + 85.136 + local class = "event " .. row_class 85.137 + if event.suggestion_id then 85.138 + class = class .. " suggestion" 85.139 + end 85.140 + 85.141 + ui.container{ attr = { class = class }, content = function() 85.142 + local event_name 85.143 + local negative_event = false 85.144 + 85.145 + local days_ago_text 85.146 + 85.147 + if mode == "timeline" then 85.148 + event_name = event.event_name 85.149 + 85.150 + if event.event == "issue_state_changed" then 85.151 + if event.state == "discussion" then 85.152 + event_name = _"Discussion started" 85.153 + elseif event.state == "verification" then 85.154 + event_name = _"Verification started" 85.155 + elseif event.state == "voting" then 85.156 + event_name = _"Voting started" 85.157 + elseif event.state == "finished_with_winner" then 85.158 + event_name = event.state_name 85.159 + elseif event.state == "finished_without_winner" then 85.160 + event_name = event.state_name 85.161 + negative_event = true 85.162 + else 85.163 + event_name = event.state_name 85.164 + negative_event = true 85.165 + end 85.166 + elseif event.event == "initiative_revoked" then 85.167 + negative_event = true 85.168 + end 85.169 + 85.170 + if event.time_ago == 0 then 85.171 + days_ago_text = _("today at #{time}", { time = format.time(event.occurrence) }) 85.172 + elseif event.time_ago == 1 then 85.173 + days_ago_text = _("yesterday at #{time}", { time = format.time(event.occurrence) }) 85.174 + else 85.175 + days_ago_text = _("#{interval} ago", { interval = format.interval_text ( event.time_ago ) } ) 85.176 + end 85.177 + 85.178 + elseif mode == "issue" then 85.179 + event_name = issue.state_name 85.180 + if issue.state_time_left:sub(1,1) ~= "-" then 85.181 + days_ago_text = _( "#{interval} left", { 85.182 + interval = format.interval_text ( issue.state_time_left ) 85.183 + }) 85.184 + elseif issue.closed then 85.185 + days_ago_text = _( "#{interval} ago", { 85.186 + interval = format.interval_text ( issue.closed_ago ) 85.187 + }) 85.188 + else 85.189 + days_ago_text = _"phase ends soon" 85.190 + end 85.191 + if issue.closed and not issue.fully_frozen then 85.192 + negative_event = true 85.193 + end 85.194 + if issue.state == "finished_without_winner" then 85.195 + negative_event = true 85.196 + end 85.197 + if issue.state == "canceled_no_initiative_admitted" then 85.198 + negative_event = true 85.199 + end 85.200 + if issue.state == "canceled_by_admin" then 85.201 + negative_event = true 85.202 + end 85.203 + end 85.204 + 85.205 + local class= "event_info" 85.206 + 85.207 + if negative_event then 85.208 + class = class .. " negative" 85.209 + end 85.210 + 85.211 + if mode == "timeline" then 85.212 + ui.container{ attr = { class = class }, content = function () 85.213 + ui.tag { content = event_name } 85.214 + slot.put ( " " ) 85.215 + ui.tag{ attr = { class = "event_time" }, content = days_ago_text } 85.216 + end } 85.217 + end 85.218 + 85.219 + if not for_issue and not for_initiative then 85.220 + ui.container{ attr = { class = "issue_context" }, content = function() 85.221 + ui.link{ 85.222 + module = "unit", view = "show", id = issue.area.unit_id, 85.223 + attr = { class = "unit" }, text = issue.area.unit.name 85.224 + } 85.225 + slot.put ( " " ) 85.226 + ui.link{ 85.227 + module = "area", view = "show", id = issue.area_id, 85.228 + attr = { class = "area" }, text = issue.area.name 85.229 + } 85.230 + slot.put ( " " ) 85.231 + execute.view{ 85.232 + module = "delegation", view = "_info", params = { 85.233 + issue = issue, member = for_member 85.234 + } 85.235 + } 85.236 + end } 85.237 + ui.container{ attr = { class = "issue_info" }, content = function() 85.238 + ui.link{ 85.239 + attr = { class = "issue" }, 85.240 + text = _("#{policy} ##{id}", { policy = issue.policy.name, id = issue.id }), 85.241 + module = "issue", 85.242 + view = "show", 85.243 + id = issue.id 85.244 + } 85.245 + 85.246 + end } 85.247 + end 85.248 + 85.249 + if mode ~= "timeline" 85.250 + or event.state == "finished_with_winner" 85.251 + or event.state == "finished_without_winner" 85.252 + then 85.253 + local initiative = issue.initiatives[1] 85.254 + if initiative then 85.255 + util.initiative_pie(initiative) 85.256 + end 85.257 + end 85.258 + 85.259 + if mode == "issue" then 85.260 + ui.container{ attr = { class = class }, content = function () 85.261 + ui.tag { content = event_name } 85.262 + slot.put ( " " ) 85.263 + ui.tag{ attr = { class = "event_time" }, content = days_ago_text } 85.264 + end } 85.265 + elseif mode == "timeline" 85.266 + and not for_issue 85.267 + and event.event ~= "issue_state_changed" 85.268 + then 85.269 + slot.put("<br />") 85.270 + end 85.271 + 85.272 + if event.suggestion_id then 85.273 + ui.container{ attr = { class = "suggestion" }, content = function() 85.274 + ui.link{ 85.275 + text = format.string(event.suggestion.name, { 85.276 + truncate_at = 160, truncate_suffix = true 85.277 + }), 85.278 + module = "initiative", view = "show", id = event.initiative.id, 85.279 + params = { suggestion_id = event.suggestion_id }, 85.280 + anchor = "s" .. event.suggestion_id 85.281 + } 85.282 + end } 85.283 + end 85.284 + 85.285 + if not for_initiative and (not for_issue or event.initiative_id) then 85.286 + 85.287 + ui.container{ attr = { class = "initiative_list" }, content = function() 85.288 + if event.initiative_id then 85.289 + local initiative = event.initiative 85.290 + 85.291 + execute.view{ module = "initiative", view = "_list", params = { 85.292 + issue = issue, 85.293 + initiative = initiative, 85.294 + for_event = mode == "timeline" and not (event.state == issue.state) 85.295 + 85.296 + } } 85.297 + else 85.298 + local initiatives = issue.initiatives 85.299 + execute.view{ module = "initiative", view = "_list", params = { 85.300 + issue = issue, 85.301 + initiatives = initiatives, 85.302 + for_event = mode == "timeline" and not (event.state == issue.state) 85.303 + } } 85.304 + end 85.305 + end } 85.306 + end 85.307 + 85.308 + end } 85.309 + end 85.310 + 85.311 + if mode == "timeline" then 85.312 + if for_sidebar then 85.313 + ui.container { attr = { class = row_class }, content = function () 85.314 + ui.link{ 85.315 + attr = { class = "moreLink" }, 85.316 + text = _"Show full history", 85.317 + module = "initiative", view = "history", id = for_initiative.id 85.318 + } 85.319 + end } 85.320 + elseif #items > limit then 85.321 + ui.container { attr = { class = row_class }, content = function () 85.322 + ui.link{ 85.323 + attr = { class = "moreLink" }, 85.324 + text = _"Show older events", 85.325 + module = request.get_module(), 85.326 + view = request.get_view(), 85.327 + id = for_unit and for_unit.id or for_area and for_area.id or for_issue and for_issue.id or for_member and for_member.id, 85.328 + params = { 85.329 + mode = "timeline", 85.330 + event_max_id = last_event_id, 85.331 + tab = param.get_all_cgi()["tab"], 85.332 + phase = param.get_all_cgi()["phase"], 85.333 + closed = param.get_all_cgi()["closed"] 85.334 + } 85.335 + } 85.336 + end } 85.337 + elseif #items < 1 then 85.338 + ui.container { attr = { class = row_class }, content = _"No more events available" } 85.339 + end 85.340 + end 85.341 + 85.342 + end } 85.343 + 85.344 +end 85.345 + 85.346 + 85.347 +local filters = {} 85.348 + 85.349 +if not for_initiative and not for_issue and not no_filter then 85.350 + filters = execute.load_chunk{module="issue", chunk="_filters.lua", params = { 85.351 + for_events = mode == "timeline" and true or false, 85.352 + member = app.session.member, 85.353 + for_member = for_member, 85.354 + state = for_state, 85.355 + for_unit = for_unit and true or false, 85.356 + for_area = for_area and true or false 85.357 + }} 85.358 +end 85.359 + 85.360 +filters.opened = true 85.361 +filters.selector = selector 85.362 + 85.363 +if mode == "timeline" then 85.364 + filters.content = doit 85.365 +else 85.366 + filters.content = function() 85.367 + ui.paginate{ 85.368 + selector = selector, 85.369 + per_page = 25, 85.370 + content = doit 85.371 + } 85.372 + end 85.373 +end 85.374 + 85.375 +ui.filters(filters) 85.376 + 85.377 \ No newline at end of file
86.1 --- a/app/main/issue/_show.lua Thu Jul 10 01:02:43 2014 +0200 86.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 86.3 @@ -1,310 +0,0 @@ 86.4 -local issue = param.get("issue", "table") 86.5 -local initiative_limit = param.get("initiative_limit", atom.integer) 86.6 -local for_member = param.get("for_member", "table") 86.7 -local for_listing = param.get("for_listing", atom.boolean) 86.8 -local for_initiative = param.get("for_initiative", "table") 86.9 -local for_initiative_id = for_initiative and for_initiative.id or nil 86.10 - 86.11 -local direct_voter 86.12 -if app.session.member_id then 86.13 - direct_voter = issue.member_info.direct_voted 86.14 -end 86.15 - 86.16 -local voteable = app.session.member_id and issue.state == 'voting' and 86.17 - app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) 86.18 - 86.19 -local vote_comment_able = app.session.member_id and issue.closed and direct_voter 86.20 - 86.21 -local vote_link_text 86.22 -if voteable then 86.23 - vote_link_text = direct_voter and _"Change vote" or _"Vote now" 86.24 -elseif vote_comment_able then 86.25 - vote_link_text = direct_voter and _"Update voting comment" 86.26 -end 86.27 - 86.28 - 86.29 -local class = "issue" 86.30 -if issue.is_interested then 86.31 - class = class .. " interested" 86.32 -elseif issue.is_interested_by_delegation_to_member_id then 86.33 - class = class .. " interested_by_delegation" 86.34 -end 86.35 - 86.36 -ui.container{ attr = { class = class }, content = function() 86.37 - 86.38 - execute.view{ module = "delegation", view = "_info", params = { issue = issue, member = for_member } } 86.39 - 86.40 - if for_listing then 86.41 - ui.container{ attr = { class = "content" }, content = function() 86.42 - ui.link{ 86.43 - module = "unit", view = "show", id = issue.area.unit_id, 86.44 - attr = { class = "unit_link" }, text = issue.area.unit.name 86.45 - } 86.46 - slot.put(" ") 86.47 - ui.link{ 86.48 - module = "area", view = "show", id = issue.area_id, 86.49 - attr = { class = "area_link" }, text = issue.area.name 86.50 - } 86.51 - end } 86.52 - end 86.53 - 86.54 - ui.container{ attr = { class = "title" }, content = function() 86.55 - 86.56 - ui.link{ 86.57 - attr = { class = "issue_id" }, 86.58 - text = _("#{policy_name} ##{issue_id}", { 86.59 - policy_name = issue.policy.name, 86.60 - issue_id = issue.id 86.61 - }), 86.62 - module = "issue", 86.63 - view = "show", 86.64 - id = issue.id 86.65 - } 86.66 - end } 86.67 - 86.68 - ui.tag{ 86.69 - attr = { class = "content issue_policy_info" }, 86.70 - tag = "div", 86.71 - content = function() 86.72 - 86.73 - ui.tag{ attr = { class = "event_name" }, content = issue.state_name } 86.74 - 86.75 - if issue.closed then 86.76 - slot.put(" · ") 86.77 - ui.tag{ content = format.interval_text(issue.closed_ago, { mode = "ago" }) } 86.78 - elseif issue.state_time_left then 86.79 - slot.put(" · ") 86.80 - if issue.state_time_left:sub(1,1) == "-" then 86.81 - if issue.state == "admission" then 86.82 - ui.tag{ content = _("Discussion starts soon") } 86.83 - elseif issue.state == "discussion" then 86.84 - ui.tag{ content = _("Verification starts soon") } 86.85 - elseif issue.state == "verification" then 86.86 - ui.tag{ content = _("Voting starts soon") } 86.87 - elseif issue.state == "voting" then 86.88 - ui.tag{ content = _("Counting starts soon") } 86.89 - end 86.90 - else 86.91 - ui.tag{ content = format.interval_text(issue.state_time_left, { mode = "time_left" }) } 86.92 - end 86.93 - end 86.94 - 86.95 - end 86.96 - } 86.97 - 86.98 - local links = {} 86.99 - 86.100 - if vote_link_text then 86.101 - links[#links+1] ={ 86.102 - content = vote_link_text, 86.103 - module = "vote", 86.104 - view = "list", 86.105 - params = { issue_id = issue.id } 86.106 - } 86.107 - end 86.108 - 86.109 - if voteable and not direct_voter then 86.110 - if not issue.member_info.non_voter then 86.111 - links[#links+1] ={ 86.112 - content = _"Do not vote directly", 86.113 - module = "vote", 86.114 - action = "non_voter", 86.115 - params = { issue_id = issue.id }, 86.116 - routing = { 86.117 - default = { 86.118 - mode = "redirect", 86.119 - module = request.get_module(), 86.120 - view = request.get_view(), 86.121 - id = param.get_id_cgi(), 86.122 - params = param.get_all_cgi() 86.123 - } 86.124 - } 86.125 - } 86.126 - else 86.127 - links[#links+1] = { attr = { class = "action" }, content = _"Do not vote directly" } 86.128 - links[#links+1] ={ 86.129 - in_brackets = true, 86.130 - content = _"Cancel [nullify]", 86.131 - module = "vote", 86.132 - action = "non_voter", 86.133 - params = { issue_id = issue.id, delete = true }, 86.134 - routing = { 86.135 - default = { 86.136 - mode = "redirect", 86.137 - module = request.get_module(), 86.138 - view = request.get_view(), 86.139 - id = param.get_id_cgi(), 86.140 - params = param.get_all_cgi() 86.141 - } 86.142 - } 86.143 - } 86.144 - end 86.145 - end 86.146 - 86.147 - if not for_member or for_member.id == app.session.member_id then 86.148 - 86.149 - if app.session.member_id then 86.150 - 86.151 - if issue.member_info.own_participation then 86.152 - if issue.closed then 86.153 - links[#links+1] = { content = _"You were interested" } 86.154 - else 86.155 - links[#links+1] = { content = _"You are interested" } 86.156 - end 86.157 - end 86.158 - 86.159 - if not issue.closed and not issue.fully_frozen then 86.160 - if issue.member_info.own_participation then 86.161 - links[#links+1] = { 86.162 - in_brackets = true, 86.163 - text = _"Withdraw", 86.164 - module = "interest", 86.165 - action = "update", 86.166 - params = { issue_id = issue.id, delete = true }, 86.167 - routing = { 86.168 - default = { 86.169 - mode = "redirect", 86.170 - module = request.get_module(), 86.171 - view = request.get_view(), 86.172 - id = param.get_id_cgi(), 86.173 - params = param.get_all_cgi() 86.174 - } 86.175 - } 86.176 - } 86.177 - elseif app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 86.178 - links[#links+1] = { 86.179 - text = _"Add my interest", 86.180 - module = "interest", 86.181 - action = "update", 86.182 - params = { issue_id = issue.id }, 86.183 - routing = { 86.184 - default = { 86.185 - mode = "redirect", 86.186 - module = request.get_module(), 86.187 - view = request.get_view(), 86.188 - id = param.get_id_cgi(), 86.189 - params = param.get_all_cgi() 86.190 - } 86.191 - } 86.192 - } 86.193 - end 86.194 - end 86.195 - 86.196 - if not issue.closed and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 86.197 - if issue.member_info.own_delegation_scope ~= "issue" then 86.198 - links[#links+1] = { text = _"Delegate issue", module = "delegation", view = "show", params = { issue_id = issue.id, initiative_id = for_initiative_id } } 86.199 - else 86.200 - links[#links+1] = { text = _"Change issue delegation", module = "delegation", view = "show", params = { issue_id = issue.id, initiative_id = for_initiative_id } } 86.201 - end 86.202 - end 86.203 - end 86.204 - 86.205 - if config.issue_discussion_url_func then 86.206 - local url = config.issue_discussion_url_func(issue) 86.207 - links[#links+1] = { 86.208 - attr = { target = "_blank" }, 86.209 - external = url, 86.210 - content = _"Discussion on issue" 86.211 - } 86.212 - end 86.213 - 86.214 - if config.etherpad and app.session.member then 86.215 - links[#links+1] = { 86.216 - attr = { target = "_blank" }, 86.217 - external = issue.etherpad_url, 86.218 - content = _"Issue pad" 86.219 - } 86.220 - end 86.221 - 86.222 - 86.223 - if app.session.member_id and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 86.224 - if not issue.fully_frozen and not issue.closed then 86.225 - links[#links+1] = { 86.226 - attr = { class = "action" }, 86.227 - text = _"Create alternative initiative", 86.228 - module = "initiative", 86.229 - view = "new", 86.230 - params = { issue_id = issue.id } 86.231 - } 86.232 - end 86.233 - end 86.234 - 86.235 - end 86.236 - 86.237 - ui.container{ attr = { class = "content actions" }, content = function() 86.238 - for i, link in ipairs(links) do 86.239 - if link.in_brackets then 86.240 - slot.put(" (") 86.241 - elseif i > 1 then 86.242 - slot.put(" · ") 86.243 - end 86.244 - if link.module or link.external then 86.245 - ui.link(link) 86.246 - else 86.247 - ui.tag(link) 86.248 - end 86.249 - if link.in_brackets then 86.250 - slot.put(")") 86.251 - end 86.252 - end 86.253 - end } 86.254 - 86.255 - if not for_listing then 86.256 - if issue.state == "canceled_by_admin" then 86.257 - ui.container{ 86.258 - attr = { class = "not_admitted_info" }, 86.259 - content = function() 86.260 - ui.container{ content = _("This issue has been canceled by administrative intervention.") } 86.261 - slot.put("<br />") 86.262 - if issue.admin_notice then 86.263 - ui.container{ content = function() slot.put(encode.html_newlines(issue.admin_notice)) end } 86.264 - end 86.265 - end 86.266 - } 86.267 - elseif issue.admin_notice then 86.268 - ui.container{ 86.269 - attr = { class = "not_admitted_info" }, 86.270 - content = function() slot.put(encode.html_newlines(issue.admin_notice)) end 86.271 - } 86.272 - end 86.273 - 86.274 - if issue.state == "canceled_issue_not_accepted" then 86.275 - local policy = issue.policy 86.276 - ui.container{ 86.277 - attr = { class = "not_admitted_info" }, 86.278 - content = _("This issue has been canceled. It failed the quorum of #{quorum}.", { quorum = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) }) 86.279 - } 86.280 - elseif 86.281 - issue.state:sub(1, #("canceled_")) == "canceled_" and 86.282 - issue.state ~= "canceled_by_admin" 86.283 - then 86.284 - ui.container{ 86.285 - attr = { class = "not_admitted_info" }, 86.286 - content = _("This issue has been canceled.") 86.287 - } 86.288 - end 86.289 - end 86.290 - 86.291 - ui.container{ attr = { class = "initiative_list content" }, content = function() 86.292 - 86.293 - local initiatives_selector = issue:get_reference_selector("initiatives") 86.294 - local highlight_string = param.get("highlight_string") 86.295 - if highlight_string then 86.296 - initiatives_selector:add_field( {'"highlight"("initiative"."name", ?)', highlight_string }, "name_highlighted") 86.297 - end 86.298 - execute.view{ 86.299 - module = "initiative", 86.300 - view = "_list", 86.301 - params = { 86.302 - issue = issue, 86.303 - initiatives_selector = initiatives_selector, 86.304 - highlight_initiative = for_initiative, 86.305 - highlight_string = highlight_string, 86.306 - no_sort = true, 86.307 - limit = (for_listing or for_initiative) and 5 or nil, 86.308 - for_member = for_member 86.309 - } 86.310 - } 86.311 - end } 86.312 -end } 86.313 -
87.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 87.2 +++ b/app/main/issue/_sidebar_issue.lua Thu Jul 10 01:19:48 2014 +0200 87.3 @@ -0,0 +1,39 @@ 87.4 +local issue = param.get("issue", "table") 87.5 +local hide_initiatives = param.get("hide_initiatives", atom.boolean) 87.6 +local highlight_initiative_id = param.get ( "highlight_initiative_id", "number" ) 87.7 + 87.8 +ui.sidebar ( "tab-whatcanido", function () 87.9 + 87.10 + ui.sidebarHead( function() 87.11 + ui.heading { 87.12 + level = 2, 87.13 + content = _"Competing initiatives" 87.14 + } 87.15 + end ) 87.16 + 87.17 + execute.view { 87.18 + module = "initiative", view = "_list", 87.19 + params = { 87.20 + issue = issue, 87.21 + initiatives = issue.initiatives, 87.22 + highlight_initiative_id = highlight_initiative_id 87.23 + } 87.24 + } 87.25 + if #issue.initiatives == 1 then 87.26 + ui.sidebarSection( function () 87.27 + 87.28 + if not issue.closed and not (issue.state == "voting") then 87.29 + ui.container { content = function() 87.30 + ui.tag { content = _"Currently this is the only initiative in this issue, because nobody started a competing initiative (yet)." } 87.31 + if app.session.member and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 87.32 + slot.put(" ") 87.33 + ui.tag { content = _"To create a competing initiative see below." } 87.34 + end 87.35 + end } 87.36 + else 87.37 + ui.container { content = _"This is the only initiative in this issue, because nobody started a competing initiative." } 87.38 + end 87.39 + end ) 87.40 + end 87.41 + 87.42 +end ) -- ui.sidebar
88.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 88.2 +++ b/app/main/issue/_sidebar_members.lua Thu Jul 10 01:19:48 2014 +0200 88.3 @@ -0,0 +1,65 @@ 88.4 +local issue = param.get("issue", "table") 88.5 +local initiative = param.get("initiative", "table") 88.6 + 88.7 +if app.session:has_access("all_pseudonymous") then 88.8 + ui.sidebar ( "tab-members", function () 88.9 + 88.10 + local text = _"Interested members" 88.11 + if issue.state == "finished_with_winner" or issue.state == "finished_without_winner" then 88.12 + text = _"Voters" 88.13 + end 88.14 + 88.15 + ui.sidebarHead( function() 88.16 + ui.heading{ 88.17 + level = 2, content = text 88.18 + } 88.19 + end ) 88.20 + 88.21 + local interested_members_selector 88.22 + 88.23 + if issue.state == "finished_with_winner" or issue.state == "finished_without_winner" then 88.24 + if initiative then 88.25 + interested_members_selector = Member:new_selector() 88.26 + :join("issue", nil, { "issue.id = ?", issue.id }) 88.27 + :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id }) 88.28 + :join("vote", nil, { "vote.member_id = member.id AND vote.initiative_id = ?", initiative.id }) 88.29 + :add_field("direct_voter.weight", "voter_weight") 88.30 + :add_field("vote.grade") 88.31 + :add_field("direct_voter.comment", "voter_comment") 88.32 + else 88.33 + interested_members_selector = Member:new_selector() 88.34 + :join("issue", nil, { "issue.id = ?", issue.id }) 88.35 + :join("direct_voter", nil, { "direct_voter.issue_id = ? AND direct_voter.member_id = member.id", issue.id }) 88.36 + :add_field("direct_voter.weight", "voter_weight") 88.37 + :add_field("direct_voter.comment", "voter_comment") 88.38 + end 88.39 + else 88.40 + interested_members_selector= issue:get_reference_selector("interested_members_snapshot") 88.41 + :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 88.42 + :add_field("direct_interest_snapshot.weight") 88.43 + :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event") 88.44 + :limit(25) 88.45 + 88.46 + if initiative then 88.47 + interested_members_selector:left_join("direct_supporter_snapshot", nil, { "direct_supporter_snapshot.initiative_id = ? AND direct_interest_snapshot.issue_id = direct_supporter_snapshot.issue_id AND direct_supporter_snapshot.member_id = direct_interest_snapshot.member_id AND direct_supporter_snapshot.event = issue.latest_snapshot_event", initiative.id }) 88.48 + interested_members_selector:add_field("direct_supporter_snapshot.member_id NOTNULL", "supporter") 88.49 + interested_members_selector:add_field("satisfied", "supporter_satisfied") 88.50 + end 88.51 + end 88.52 + 88.53 + execute.view{ 88.54 + module = "member", 88.55 + view = "_list", 88.56 + params = { 88.57 + issue = issue, 88.58 + initiative = initiative, 88.59 + members_selector = interested_members_selector, 88.60 + no_filter = true, no_paginate = true, 88.61 + member_class = "sidebarRow sidebarRowNarrow", 88.62 + for_votes = issue.state == "finished_with_winner" or issue.state == "finished_without_winner" 88.63 + } 88.64 + } 88.65 + 88.66 + end ) 88.67 + 88.68 +end
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/app/main/issue/_sidebar_state.lua Thu Jul 10 01:19:48 2014 +0200 89.3 @@ -0,0 +1,171 @@ 89.4 +local issue = param.get("issue", "table") 89.5 +local initiative = param.get("initiative", "table") 89.6 + 89.7 +local view_module 89.8 +local view_id 89.9 + 89.10 +if initiative then 89.11 + issue = initiative.issue 89.12 + view_module = "initiative" 89.13 + view_id = initiative.id 89.14 +else 89.15 + view_module = "issue" 89.16 + view_id = issue.id 89.17 +end 89.18 + 89.19 +ui.sidebar( "tab-whatcanido", function() 89.20 + 89.21 + ui.sidebarHead( function() 89.22 + ui.heading{ level = 2, content = function() 89.23 + ui.link{ 89.24 + content = issue.name, 89.25 + module = "issue", view = "show", id = issue.id 89.26 + } 89.27 + end } 89.28 + end ) 89.29 + 89.30 + local current_occured = false 89.31 + local failed = false 89.32 + 89.33 + for i, state in ipairs{ "admission", "discussion", "verification", "voting" } do 89.34 + local current = state == issue.state 89.35 + 89.36 + if current then 89.37 + current_occured = true 89.38 + end 89.39 + 89.40 + local phase_success = ( 89.41 + (state == "admission" and issue.accepted) 89.42 + or (state == "discussion" and issue.half_frozen) 89.43 + or (state == "verification" and issue.fully_frozen and issue.state ~= "canceled_no_initiative_admitted") 89.44 + or (state == "voting" and issue.closed and issue.state ~= "canceled_no_initiative_admitted" and issue.state ~= "canceled_by_admin") 89.45 + ) 89.46 + 89.47 + if not failed then 89.48 + ui.sidebarSection( "sidebarRowNarrow" .. (current and " highlightedx" or ""), function() 89.49 + 89.50 + local state_names = { 89.51 + admission = _"Admission", 89.52 + discussion = _"Discussion", 89.53 + verification = _"Verification", 89.54 + voting = _"Voting" 89.55 + } 89.56 + 89.57 + local state_name = "(" .. i .. ") " .. state_names[state] or state 89.58 + 89.59 + local function quorum_text(policy, quorum) 89.60 + local num 89.61 + local den 89.62 + 89.63 + if quorum == 1 then 89.64 + num = policy.issue_quorum_num 89.65 + den = policy.issue_quorum_den 89.66 + elseif quorum == 2 then 89.67 + num = policy.initiative_quorum_num 89.68 + den = policy.initiative_quorum_den 89.69 + end 89.70 + 89.71 + if den == 100 then 89.72 + return _("#{percentage}%", { percentage = num }) 89.73 + else 89.74 + return num .. "/" .. den 89.75 + end 89.76 + 89.77 + end 89.78 + 89.79 + local quorum 89.80 + if state == "admission" then 89.81 + quorum = quorum_text(issue.policy, 1) 89.82 + elseif state == "verification" then 89.83 + quorum = quorum_text(issue.policy, 2) 89.84 + end 89.85 + 89.86 + if current then 89.87 + local time_left 89.88 + if issue.state_time_left:sub(1,1) ~= "-" then 89.89 + time_left = format.interval_text(issue.state_time_left, { mode = "time_left" }) 89.90 + else 89.91 + time_left = "phase ends soon" 89.92 + end 89.93 + 89.94 + ui.tag{ attr = { class = "right" }, 89.95 + content = time_left 89.96 + } 89.97 + elseif current_occured then 89.98 + local phase_duration = issue[state .. "_time"] 89.99 + ui.tag{ attr = { class = "right" }, 89.100 + content = _("#{duration}", { 89.101 + duration = format.interval_text(phase_duration) 89.102 + } ) 89.103 + } 89.104 + else 89.105 + local text = "failed" 89.106 + if quorum then 89.107 + text = _("failed #{quorum}", { quorum = quorum }) 89.108 + end 89.109 + if phase_success then 89.110 + if quorum then 89.111 + text = _("reached #{quorum}", { quorum = quorum }) 89.112 + else 89.113 + text = _"finished" 89.114 + end 89.115 + elseif issue.state == "canceled_revoked_before_accepted" or 89.116 + issue.state == "canceled_after_revocation_during_discussion" or 89.117 + issue.state == "canceled_after_revocation_during_verification" 89.118 + then 89.119 + text = _"revoked" 89.120 + elseif issue.state == "canceled_by_admin" then 89.121 + text = _"canceled" 89.122 + end 89.123 + 89.124 + ui.tag{ attr = { class = "right" }, 89.125 + content = text 89.126 + } 89.127 + end 89.128 + 89.129 + ui.heading{ level = 3, content = function() 89.130 + if current then 89.131 + ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_current.png" } 89.132 + elseif not current_occured and not phase_success then 89.133 + ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_failed.png" } 89.134 + elseif current_occured then 89.135 + ui.image{ attr = { class = "icon16" }, static = "icons/32/empty.png" } 89.136 + else 89.137 + ui.image{ attr = { class = "icon16" }, static = "icons/32/phase_finished.png" } 89.138 + end 89.139 + slot.put(" ") 89.140 + ui.tag{ content = state_name } 89.141 + end } 89.142 + 89.143 + local help_texts = { 89.144 + admission = _"As soon as one initiative of this issue reaches #{quorum} support, the issue will go into discussion phase.", 89.145 + discussion = _"During the discussion phase the issue is debated between initiators while the initiatives are improved by suggestions from the supporters.", 89.146 + verification = _"During the verification phase the initiative drafts cannot be changed anymore.", 89.147 + voting = _"On this issue can be voted now." 89.148 + } 89.149 + if current then 89.150 + -- ui.container { content = help_texts[state] } 89.151 + end 89.152 + 89.153 + 89.154 + end ) 89.155 + end 89.156 + 89.157 + if not phase_success and not current and not current_occured then 89.158 + failed = true 89.159 + end 89.160 + end 89.161 + 89.162 + if issue.closed then 89.163 + ui.sidebarSection( function() 89.164 + ui.heading { level = 1, content = issue.state_name } 89.165 + end ) 89.166 + if issue.admin_notice then 89.167 + ui.sidebarSection( function() 89.168 + ui.heading { level = 3, content = _"Administrative notice:" } 89.169 + slot.put(encode.html_newlines(issue.admin_notice)) 89.170 + end ) 89.171 + end 89.172 + end 89.173 + 89.174 +end ) 89.175 \ No newline at end of file
90.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 90.2 +++ b/app/main/issue/_sidebar_whatcanido.lua Thu Jul 10 01:19:48 2014 +0200 90.3 @@ -0,0 +1,631 @@ 90.4 +local issue = param.get("issue", "table") 90.5 +local initiative = param.get("initiative", "table") 90.6 +local member = param.get("member", "table") or app.session.member 90.7 + 90.8 +if initiative then 90.9 + issue = initiative.issue 90.10 +end 90.11 + 90.12 +local privileged_to_vote = app.session.member and app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) 90.13 + 90.14 +local active_trustee_id 90.15 +if member then 90.16 + if not issue.member_info.own_participation then 90.17 + if issue.member_info.first_trustee_participation then 90.18 + active_trustee_id = issue.member_info.first_trustee_id 90.19 + elseif issue.member_info.other_trustee_participation then 90.20 + active_trustee_id = issue.member_info.other_trustee_id 90.21 + end 90.22 + end 90.23 +end 90.24 + 90.25 +ui.sidebar ( "tab-whatcanido", function () 90.26 + 90.27 + ui.sidebarHeadWhatCanIDo() 90.28 + 90.29 + local supporter 90.30 + 90.31 + if initiative and app.session.member_id then 90.32 + supporter = app.session.member:get_reference_selector("supporters") 90.33 + :add_where{ "initiative_id = ?", initiative.id } 90.34 + :optional_object_mode() 90.35 + :exec() 90.36 + end 90.37 + 90.38 + local view_module 90.39 + local view_id 90.40 + 90.41 + if initiative then 90.42 + issue = issue 90.43 + view_module = "initiative" 90.44 + view_id = initiative.id 90.45 + else 90.46 + view_module = "issue" 90.47 + view_id = issue.id 90.48 + end 90.49 + 90.50 + local initiator 90.51 + if initiative and app.session.member_id then 90.52 + initiator = Initiator:by_pk(initiative.id, app.session.member.id) 90.53 + end 90.54 + 90.55 + local initiators 90.56 + 90.57 + if initiative then 90.58 + local initiators_members_selector = initiative:get_reference_selector("initiating_members") 90.59 + :add_field("initiator.accepted", "accepted") 90.60 + :add_order_by("member.name") 90.61 + if initiator and initiator.accepted then 90.62 + initiators_members_selector:add_where("initiator.accepted ISNULL OR initiator.accepted") 90.63 + else 90.64 + initiators_members_selector:add_where("initiator.accepted") 90.65 + end 90.66 + 90.67 + initiators = initiators_members_selector:exec() 90.68 + end 90.69 + 90.70 + if initiator and 90.71 + initiator.accepted and 90.72 + not issue.fully_frozen and 90.73 + not issue.closed and 90.74 + not initiative.revoked 90.75 + then 90.76 + 90.77 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.78 + ui.heading { level = 3, content = function() 90.79 + ui.tag { content = _"You are initiator of this initiative" } 90.80 + end } 90.81 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.82 + ui.tag { tag = "li", content = function () 90.83 + ui.link{ 90.84 + module = "draft", view = "new", 90.85 + params = { initiative_id = initiative.id }, 90.86 + content = _"edit proposal and/or reasons" 90.87 + } 90.88 + end } 90.89 + ui.tag { tag = "li", content = function () 90.90 + ui.link{ 90.91 + attr = { class = "action" }, 90.92 + module = "initiative", view = "add_initiator", 90.93 + params = { initiative_id = initiative.id }, 90.94 + content = _"invite another initiator" 90.95 + } 90.96 + end } 90.97 + if #initiative.initiators > 1 then 90.98 + ui.tag { tag = "li", content = function () 90.99 + ui.link{ 90.100 + module = "initiative", view = "remove_initiator", 90.101 + params = { initiative_id = initiative.id }, 90.102 + content = _"remove an initiator" 90.103 + } 90.104 + end } 90.105 + end 90.106 + ui.tag { tag = "li", content = function () 90.107 + ui.link{ 90.108 + module = "initiative", view = "revoke", id = initiative.id, 90.109 + content = _"revoke initiative" 90.110 + } 90.111 + end } 90.112 + end } 90.113 + end } 90.114 + end 90.115 + 90.116 + -- invited as initiator 90.117 + if initiator and initiator.accepted == nil and not initiative.issue.half_frozen and not initiative.issue.closed then 90.118 + ui.container { attr = { class = "sidebarRow highlighted" }, content = function () 90.119 + ui.heading { level = 3, content = function() 90.120 + ui.tag { content = _"You are invited to become initiator of this initiative" } 90.121 + end } 90.122 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.123 + ui.tag{ tag = "li", content = function () 90.124 + ui.link{ 90.125 + content = _"accept invitation", 90.126 + module = "initiative", 90.127 + action = "accept_invitation", 90.128 + id = initiative.id, 90.129 + routing = { 90.130 + default = { 90.131 + mode = "redirect", 90.132 + module = request.get_module(), 90.133 + view = request.get_view(), 90.134 + id = param.get_id_cgi(), 90.135 + params = param.get_all_cgi() 90.136 + } 90.137 + } 90.138 + } 90.139 + end } 90.140 + 90.141 + ui.tag{ tag = "li", content = function () 90.142 + ui.link{ 90.143 + content = _"refuse invitation", 90.144 + module = "initiative", 90.145 + action = "reject_initiator_invitation", 90.146 + params = { 90.147 + initiative_id = initiative.id, 90.148 + member_id = app.session.member.id 90.149 + }, 90.150 + routing = { 90.151 + default = { 90.152 + mode = "redirect", 90.153 + module = request.get_module(), 90.154 + view = request.get_view(), 90.155 + id = param.get_id_cgi(), 90.156 + params = param.get_all_cgi() 90.157 + } 90.158 + } 90.159 + } 90.160 + end } 90.161 + end } 90.162 + end } 90.163 + end 90.164 + 90.165 + 90.166 + if privileged_to_vote and issue.member_info.first_trustee_id then 90.167 + local member = Member:by_id(issue.member_info.first_trustee_id) 90.168 + ui.sidebarSection( function () 90.169 + ui.container { attr = { class = "right" }, content = function() 90.170 + execute.view{ 90.171 + module = "member_image", 90.172 + view = "_show", 90.173 + params = { 90.174 + member = member, 90.175 + image_type = "avatar", 90.176 + show_dummy = true 90.177 + } 90.178 + } 90.179 + end } 90.180 + if issue.member_info.own_delegation_scope == "unit" then 90.181 + ui.heading{ level = 3, content = _"You delegated this organizational unit" } 90.182 + elseif issue.member_info.own_delegation_scope == "area" then 90.183 + ui.heading{ level = 3, content = _"You delegated this subject area" } 90.184 + elseif issue.member_info.own_delegation_scope == "issue" then 90.185 + ui.heading{ level = 3, content = _"You delegated this issue" } 90.186 + end 90.187 + 90.188 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.189 + if issue.member_info.own_delegation_scope == "area" or 90.190 + issue.member_info.own_delegation_scope == "unit" then 90.191 + ui.tag { tag = "li", content = function () 90.192 + ui.link { 90.193 + module = "delegation", view = "show", params = { 90.194 + issue_id = issue.id, 90.195 + initiative_id = initiative and initiative.id or nil 90.196 + }, 90.197 + content = _"change/revoke delegation only for this issue" 90.198 + } 90.199 + end } 90.200 + end 90.201 + if issue.member_info.own_delegation_scope == "unit" then 90.202 + ui.tag { tag = "li", content = function () 90.203 + ui.link { 90.204 + module = "delegation", view = "show", params = { 90.205 + unit_id = issue.area.unit_id, 90.206 + }, 90.207 + content = _("change/revoke delegation of organizational unit", { 90.208 + unit_name = issue.area.unit.name 90.209 + }) 90.210 + } 90.211 + end } 90.212 + elseif issue.member_info.own_delegation_scope == "area" then 90.213 + ui.tag { tag = "li", content = function () 90.214 + ui.link { 90.215 + module = "delegation", view = "show", params = { 90.216 + area_id = issue.area_id, 90.217 + }, 90.218 + content = _"change/revoke delegation of subject area" 90.219 + } 90.220 + end } 90.221 + end 90.222 + if issue.member_info.own_delegation_scope == nil then 90.223 + ui.tag { tag = "li", content = function () 90.224 + ui.link { 90.225 + module = "delegation", view = "show", params = { 90.226 + issue_id = issue.id, 90.227 + initiative_id = initiative and initiative.id or nil 90.228 + }, 90.229 + content = _"choose issue delegatee" 90.230 + } 90.231 + end } 90.232 + elseif issue.member_info.own_delegation_scope == "issue" then 90.233 + ui.tag { tag = "li", content = function () 90.234 + ui.link { 90.235 + module = "delegation", view = "show", params = { 90.236 + issue_id = issue.id, 90.237 + initiative_id = initiative and initiative.id or nil 90.238 + }, 90.239 + content = _"change/revoke issue delegation" 90.240 + } 90.241 + end } 90.242 + end 90.243 + end } 90.244 + 90.245 + if issue.member_info.first_trustee_id and issue.member_info.own_participation then 90.246 + local text = _"As long as you are interested in this issue yourself, the delegation is suspended for this issue, but it will be applied again in the voting phase unless you vote yourself." 90.247 + if issue.state == "voting" then 90.248 + text = _"This delegation is suspended, because you voted yourself." 90.249 + end 90.250 + ui.container { content = text } 90.251 + end 90.252 + end ) 90.253 + end 90.254 + 90.255 + if privileged_to_vote and not issue.closed and not issue.fully_frozen then 90.256 + if issue.member_info.own_participation then 90.257 + ui.sidebarSection( function () 90.258 + ui.container{ attr = { class = "right" }, content = function() 90.259 + ui.image{ attr = { class = "right" }, static = "icons/48/eye.png" } 90.260 + if issue.member_info.weight and issue.member_info.weight > 1 then 90.261 + slot.put("<br />") 90.262 + ui.tag{ 90.263 + attr = { class = "right" }, 90.264 + content = "+" .. issue.member_info.weight - 1 90.265 + } 90.266 + end 90.267 + end } 90.268 + ui.heading{ level = 3, content = _("You are interested in this issue", { id = issue.id }) } 90.269 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.270 + if issue.member_info.weight and issue.member_info.weight > 1 then 90.271 + ui.tag { tag = "li", content = function () 90.272 + ui.link { 90.273 + module = "delegation", view = "show_incoming", 90.274 + params = { issue_id = issue.id, member_id = app.session.member_id }, 90.275 + content = _("you have #{count} incoming delegations", { 90.276 + count = issue.member_info.weight - 1 90.277 + }) 90.278 + } 90.279 + end } 90.280 + end 90.281 + ui.tag { tag = "li", content = function () 90.282 + ui.link { 90.283 + module = "interest", action = "update", 90.284 + routing = { default = { 90.285 + mode = "redirect", module = view_module, view = "show", id = view_id 90.286 + } }, 90.287 + params = { issue_id = issue.id, delete = true }, 90.288 + text = _"remove my interest" 90.289 + } 90.290 + end } 90.291 + end } 90.292 + end ) 90.293 + else 90.294 + ui.sidebarSection( function () 90.295 + ui.heading{ level = 3, content = _("I want to participate in this issue", { id = issue.id }) } 90.296 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.297 + ui.tag { tag = "li", content = function () 90.298 + ui.link { 90.299 + module = "interest", action = "update", 90.300 + params = { issue_id = issue.id }, 90.301 + routing = { default = { 90.302 + mode = "redirect", module = view_module, view = "show", id = view_id 90.303 + } }, 90.304 + text = _"add my interest" 90.305 + } 90.306 + end } 90.307 + ui.tag { tag = "li", content = _"browse through the competing initiatives" } 90.308 + end } 90.309 + end ) 90.310 + end 90.311 + 90.312 + if initiative then 90.313 + 90.314 + if not initiative.member_info.supported or active_trustee_id then 90.315 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.316 + ui.heading { level = 3, content = function() 90.317 + ui.tag { content = _"I like this initiative and I want to support it" } 90.318 + end } 90.319 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.320 + ui.tag { tag = "li", content = function () 90.321 + ui.link { 90.322 + module = "initiative", action = "add_support", 90.323 + routing = { default = { 90.324 + mode = "redirect", module = "initiative", view = "show", id = initiative.id 90.325 + } }, 90.326 + id = initiative.id, 90.327 + text = _"add my support" 90.328 + } 90.329 + end } 90.330 + end } 90.331 + end } 90.332 + 90.333 + else -- if not supported 90.334 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.335 + if initiative.member_info.satisfied then 90.336 + ui.image{ attr = { class = "right icon48" }, static = "icons/32/support_satisfied.png" } 90.337 + else 90.338 + ui.image{ attr = { class = "right icon48" }, static = "icons/32/support_unsatisfied.png" } 90.339 + end 90.340 + ui.heading { level = 3, content = _"You are supporting this initiative" } 90.341 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.342 + if not initiative.member_info.satisfied then 90.343 + ui.tag { tag = "li", content = function () 90.344 + ui.tag { content = function () 90.345 + ui.link { 90.346 + external = "#suggestions", 90.347 + content = _"you restricted your support by rating suggestions as must or must not" 90.348 + } 90.349 + end } 90.350 + end } 90.351 + end 90.352 + ui.tag { tag = "li", content = function () 90.353 + ui.tag { content = function () 90.354 + ui.link { 90.355 + xattr = { class = "btn btn-remove" }, 90.356 + module = "initiative", action = "remove_support", 90.357 + routing = { default = { 90.358 + mode = "redirect", module = "initiative", view = "show", id = initiative.id 90.359 + } }, 90.360 + id = initiative.id, 90.361 + text = _"remove my support" 90.362 + } 90.363 + end } 90.364 + end } 90.365 + end } 90.366 + end } 90.367 + 90.368 + end -- not supported 90.369 + 90.370 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.371 + ui.heading { level = 3, content = _"I want to improve this initiative" } 90.372 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.373 + if issue.state == "verification" then 90.374 + ui.tag { tag = "li", content = _"this issue is in verification phase, therefore the initiative text cannot be updated anymore" } 90.375 + elseif issue.state == "voting" then 90.376 + ui.tag { tag = "li", content = _"this issue is in voting phase, therefore the initiative text cannot be updated anymore" } 90.377 + else 90.378 + 90.379 + if initiative.member_info.initiated then 90.380 + ui.tag { tag = "li", content =_"take a look at the suggestions of your supporters" } 90.381 + ui.tag { tag = "li", content =_"if you like to implement a suggestion in your proposal and/or reasons, update your initiative draft" } 90.382 + ui.tag { tag = "li", content =_"to argue about suggestions, just add your arguments to your reasons in the initiative draft, so your supporters can learn about your opinion" } 90.383 + end 90.384 + 90.385 + if not initiative.member_info.supported or active_trustee_id then 90.386 + ui.tag { tag = "li", content =_"add your support (see above) and rate or write new suggestions (and thereby restrict your support to certain conditions if necessary)" } 90.387 + else 90.388 + ui.tag { tag = "li", content = _"take a look at the suggestions (see left) and rate them" } 90.389 + ui.tag { tag = "li", content = function () 90.390 + ui.link { 90.391 + module = "suggestion", view = "new", params = { 90.392 + initiative_id = initiative.id 90.393 + }, 90.394 + content = _"write a new suggestion" 90.395 + } 90.396 + end } 90.397 + end 90.398 + end 90.399 + end } 90.400 + end } 90.401 + 90.402 + end 90.403 + 90.404 + if 90.405 + (issue.state == "admission" or 90.406 + issue.state == "discussion" or 90.407 + issue.state == "verification") 90.408 + then 90.409 + ui.sidebarSection( function () 90.410 + if initiative then 90.411 + ui.heading{ level = 3, content = _"I don't like this initiative and I want to add my opinion or counter proposal" } 90.412 + else 90.413 + ui.heading{ level = 3, content = _"I don't like any of the initiative in this issue and I want to add my opinion or counter proposal" } 90.414 + end 90.415 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.416 + ui.tag { tag = "li", content = function () 90.417 + ui.link { 90.418 + module = "issue", view = "show", id = issue.id, 90.419 + content = _"take a look at the competing initiatives" 90.420 + } 90.421 + end } 90.422 + ui.tag { tag = "li", content = function () 90.423 + ui.link { 90.424 + module = "initiative", view = "new", 90.425 + params = { issue_id = issue.id }, 90.426 + content = _"start a new competing initiative" 90.427 + } 90.428 + end } 90.429 + end } 90.430 + end ) 90.431 + end 90.432 + 90.433 + if not issue.member_info.first_trustee_id then 90.434 + ui.sidebarSection( function () 90.435 + ui.heading{ level = 3, content = _"I want to delegate this issue" } 90.436 + 90.437 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.438 + ui.tag { tag = "li", content = function () 90.439 + ui.link { 90.440 + module = "delegation", view = "show", params = { 90.441 + issue_id = issue.id, 90.442 + initiative_id = initiative and initiative.id or nil 90.443 + }, 90.444 + content = _"choose issue delegatee" 90.445 + } 90.446 + end } 90.447 + end } 90.448 + end ) 90.449 + end 90.450 + 90.451 + end 90.452 + 90.453 + if initiator and initiator.accepted == false then 90.454 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.455 + ui.heading { level = 3, content = function() 90.456 + ui.tag { content = _"You refused to become initiator of this initiative" } 90.457 + end } 90.458 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.459 + ui.tag{ tag = "li", content = function () 90.460 + ui.link{ 90.461 + text = _"allow invitation again", 90.462 + module = "initiative", 90.463 + action = "remove_initiator", 90.464 + params = { 90.465 + initiative_id = initiative.id, 90.466 + member_id = app.session.member.id 90.467 + }, 90.468 + routing = { 90.469 + ok = { 90.470 + mode = "redirect", 90.471 + module = "initiative", 90.472 + view = "show", 90.473 + id = initiative.id 90.474 + } 90.475 + } 90.476 + } 90.477 + end } 90.478 + end } 90.479 + end } 90.480 + end 90.481 + 90.482 + 90.483 + 90.484 + if privileged_to_vote then 90.485 + 90.486 + if initiative and 90.487 + (issue.state == "admission" or 90.488 + issue.state == "discussion" or 90.489 + issue.state == "verification") 90.490 + then 90.491 + 90.492 + elseif issue.state == "verification" then 90.493 + 90.494 + elseif issue.state == "voting" then 90.495 + if not issue.member_info.direct_voted then 90.496 + if not issue.member_info.non_voter then 90.497 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.498 + ui.heading { level = 3, content = _"I like to vote on this issue:" } 90.499 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.500 + ui.tag { tag = "li", content = function () 90.501 + ui.tag { content = function () 90.502 + if not issue.closed then 90.503 + ui.link { 90.504 + xattr = { class = "btn btn-vote" }, 90.505 + module = "vote", view = "list", 90.506 + params = { issue_id = issue.id }, 90.507 + text = _"vote now" 90.508 + } 90.509 + end 90.510 + end } 90.511 + end } 90.512 + end } 90.513 + end } 90.514 + end 90.515 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.516 + if not issue.member_info.non_voter then 90.517 + ui.heading { level = 3, content = _"I don't like to vote this issue (myself):" } 90.518 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.519 + ui.tag { tag = "li", content = function () 90.520 + ui.link{ 90.521 + content = _"do not notify me about this voting anymore", 90.522 + module = "vote", 90.523 + action = "non_voter", 90.524 + params = { issue_id = issue.id }, 90.525 + routing = { 90.526 + default = { 90.527 + mode = "redirect", 90.528 + module = request.get_module(), 90.529 + view = request.get_view(), 90.530 + id = param.get_id_cgi(), 90.531 + params = param.get_all_cgi() 90.532 + } 90.533 + } 90.534 + } 90.535 + end } 90.536 + end } 90.537 + else 90.538 + ui.heading { level = 3, content = _"You do not like to vote this issue (yourself)" } 90.539 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.540 + ui.tag { tag = "li", content = function () 90.541 + ui.link{ 90.542 + in_brackets = true, 90.543 + content = _"discard", 90.544 + module = "vote", 90.545 + action = "non_voter", 90.546 + params = { issue_id = issue.id, delete = true }, 90.547 + routing = { 90.548 + default = { 90.549 + mode = "redirect", 90.550 + module = request.get_module(), 90.551 + view = request.get_view(), 90.552 + id = param.get_id_cgi(), 90.553 + params = param.get_all_cgi() 90.554 + } 90.555 + } 90.556 + } 90.557 + end } 90.558 + end } 90.559 + end 90.560 + end } 90.561 + else 90.562 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.563 + ui.heading { level = 3, content = _"I like to change/revoke my vote:" } 90.564 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.565 + ui.tag { tag = "li", content = function () 90.566 + ui.tag { content = function () 90.567 + if not issue.closed then 90.568 + ui.link { 90.569 + xattr = { class = "btn btn-vote" }, 90.570 + module = "vote", view = "list", 90.571 + params = { issue_id = issue.id }, 90.572 + text = _"change my vote" 90.573 + } 90.574 + end 90.575 + end } 90.576 + end } 90.577 + ui.tag { tag = "li", content = function () 90.578 + ui.tag { content = function () 90.579 + if not issue.closed then 90.580 + ui.link { 90.581 + module = "vote", action = "update", 90.582 + params = { 90.583 + issue_id = issue.id, 90.584 + discard = true 90.585 + }, 90.586 + routing = { 90.587 + default = { 90.588 + mode = "redirect", 90.589 + module = "issue", 90.590 + view = "show", 90.591 + id = issue.id 90.592 + } 90.593 + }, 90.594 + text = _"discard my vote" 90.595 + } 90.596 + end 90.597 + end } 90.598 + end } 90.599 + end } 90.600 + 90.601 + end } 90.602 + 90.603 + end 90.604 + end 90.605 + end 90.606 + 90.607 + if app.session.member and not privileged_to_vote then 90.608 + ui.sidebarSection( _"You are not entitled to vote in this unit" ) 90.609 + end 90.610 + 90.611 + if issue.closed then 90.612 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.613 + ui.heading { level = 3, content = _"This issue is closed" } 90.614 + end } 90.615 + end 90.616 + 90.617 + if initiative and config.tell_others and config.tell_others.initiative then 90.618 + ui.container { attr = { class = "sidebarRow" }, content = function () 90.619 + 90.620 + ui.heading { level = 3, content = _"Tell others about this initiative:" } 90.621 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 90.622 + 90.623 + for i, link in ipairs (config.tell_others.initiative(initiative)) do 90.624 + ui.tag { tag = "li", content = function () 90.625 + ui.link ( link ) 90.626 + end } 90.627 + end 90.628 + 90.629 + end } 90.630 + end } 90.631 + end 90.632 + 90.633 + 90.634 +end )
91.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 91.2 +++ b/app/main/issue/history.lua Thu Jul 10 01:19:48 2014 +0200 91.3 @@ -0,0 +1,47 @@ 91.4 +local issue = Issue:by_id(param.get_id()) 91.5 +issue:load_everything_for_member_id ( app.session.member_id ) 91.6 + 91.7 +execute.view { 91.8 + module = "issue", view = "_head", 91.9 + params = { issue = issue, member = app.session.member } 91.10 +} 91.11 + 91.12 +execute.view { 91.13 + module = "issue", view = "_sidebar_issue", params = { 91.14 + issue = issue, 91.15 + hide_initiatives = true 91.16 + } 91.17 +} 91.18 + 91.19 +execute.view{ module = "issue", view = "_sidebar_state", params = { 91.20 + issue = issue 91.21 +} } 91.22 + 91.23 +execute.view { 91.24 + module = "issue", view = "_sidebar_whatcanido", params = { 91.25 + issue = issue 91.26 + } 91.27 +} 91.28 + 91.29 +execute.view { 91.30 + module = "issue", view = "_sidebar_members", params = { 91.31 + issue = issue 91.32 + } 91.33 +} 91.34 + 91.35 + 91.36 + 91.37 +ui.section( function() 91.38 + 91.39 + execute.view{ 91.40 + module = "issue", view = "_head2", params = { 91.41 + issue = issue, for_history = true 91.42 + } 91.43 + } 91.44 + 91.45 + execute.view { 91.46 + module = "issue", view = "_list2", params = { for_issue = issue } 91.47 + } 91.48 + 91.49 +end ) 91.50 +
92.1 --- a/app/main/issue/list.lua Thu Jul 10 01:02:43 2014 +0200 92.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 92.3 @@ -1,7 +0,0 @@ 92.4 -local issues_selector = Issue:new_selector() 92.5 - 92.6 -execute.view{ 92.7 - module = "issue", 92.8 - view = "_list", 92.9 - params = { issues_selector = issues_selector } 92.10 -} 92.11 \ No newline at end of file
93.1 --- a/app/main/issue/show.lua Thu Jul 10 01:02:43 2014 +0200 93.2 +++ b/app/main/issue/show.lua Thu Jul 10 01:19:48 2014 +0200 93.3 @@ -1,52 +1,126 @@ 93.4 -local issue = Issue:by_id(param.get_id()) 93.5 +local issue = Issue:by_id ( param.get_id () ) 93.6 + 93.7 +if not issue then 93.8 + execute.view { module = "index", view = "404" } 93.9 + request.set_status("404 Not Found") 93.10 + return 93.11 +end 93.12 + 93.13 +local initiatives = issue.initiatives 93.14 + 93.15 if app.session.member_id then 93.16 - issue:load_everything_for_member_id(app.session.member_id) 93.17 + issue:load_everything_for_member_id ( app.session.member_id ) 93.18 + initiatives:load_everything_for_member_id ( app.session.member_id ) 93.19 end 93.20 93.21 if not app.html_title.title then 93.22 - app.html_title.title = _("Issue ##{id}", { id = issue.id }) 93.23 + app.html_title.title = _("Issue ##{id}", { id = issue.id }) 93.24 end 93.25 93.26 -slot.select("head", function() 93.27 - execute.view{ module = "area", view = "_head", params = { area = issue.area } } 93.28 -end) 93.29 - 93.30 -util.help("issue.show") 93.31 +execute.view { 93.32 + module = "issue", view = "_head", 93.33 + params = { issue = issue, member = app.session.member } 93.34 +} 93.35 93.36 -slot.select("head", function() 93.37 - execute.view{ module = "issue", view = "_show", params = { issue = issue } } 93.38 -end ) 93.39 - 93.40 -if app.session:has_access("all_pseudonymous") then 93.41 +execute.view{ module = "issue", view = "_sidebar_state", params = { 93.42 + issue = issue 93.43 +} } 93.44 93.45 - ui.container{ attr = { class = "heading" }, content = _"Interested members" } 93.46 - 93.47 - local interested_members_selector = issue:get_reference_selector("interested_members_snapshot") 93.48 - :join("issue", nil, "issue.id = direct_interest_snapshot.issue_id") 93.49 - :add_field("direct_interest_snapshot.weight") 93.50 - :add_where("direct_interest_snapshot.event = issue.latest_snapshot_event") 93.51 +execute.view { 93.52 + module = "issue", view = "_sidebar_whatcanido", params = { 93.53 + issue = issue 93.54 + } 93.55 +} 93.56 93.57 - execute.view{ 93.58 - module = "member", 93.59 - view = "_list", 93.60 - params = { 93.61 - issue = issue, 93.62 - members_selector = interested_members_selector 93.63 +execute.view { 93.64 + module = "issue", view = "_sidebar_members", params = { 93.65 + issue = issue 93.66 + } 93.67 +} 93.68 + 93.69 +ui.section( function () 93.70 + 93.71 + execute.view{ 93.72 + module = "issue", view = "_head2", params = { 93.73 + issue = issue 93.74 } 93.75 } 93.76 93.77 - ui.container{ attr = { class = "heading" }, content = _"Details" } 93.78 - 93.79 - execute.view{ 93.80 - module = "issue", 93.81 - view = "_details", 93.82 - params = { issue = issue } 93.83 - } 93.84 + if issue.initiatives[1].rank == 1 then 93.85 + execute.view{ module = "initiative", view = "_sidebar_state", params = { 93.86 + initiative = issue.initiatives[1] 93.87 + } } 93.88 + end 93.89 93.90 -end 93.91 + ui.sectionRow( function () 93.92 + execute.view { 93.93 + module = "initiative", view = "_list", 93.94 + params = { 93.95 + issue = issue, 93.96 + initiatives = initiatives 93.97 + } 93.98 + } 93.99 + end ) 93.100 + 93.101 +end ) 93.102 93.103 -if issue.snapshot then 93.104 - slot.put("<br />") 93.105 - ui.field.timestamp{ label = _"Last snapshot:", value = issue.snapshot } 93.106 -end 93.107 +ui.section(function() 93.108 + ui.sectionHead( function() 93.109 + ui.heading { level = 1, content = _"Details" } 93.110 + end ) 93.111 + local policy = issue.policy 93.112 + ui.form{ 93.113 + record = issue, 93.114 + readonly = true, 93.115 + attr = { class = "sectionRow form" }, 93.116 + content = function() 93.117 + if issue.snapshot then 93.118 + ui.field.timestamp{ label = _"Last counting:", value = issue.snapshot } 93.119 + end 93.120 + ui.field.text{ label = _"Population", name = "population" } 93.121 + ui.field.timestamp{ label = _"Created at", name = "created" } 93.122 + if policy.polling then 93.123 + ui.field.text{ label = _"Admission time", value = _"Implicitly admitted" } 93.124 + else 93.125 + ui.field.text{ label = _"Admission time", value = format.interval_text(issue.admission_time_text) } 93.126 + ui.field.text{ 93.127 + label = _"Issue quorum", 93.128 + value = format.percentage(policy.issue_quorum_num / policy.issue_quorum_den) 93.129 + } 93.130 + if issue.population then 93.131 + ui.field.text{ 93.132 + label = _"Currently required", 93.133 + value = math.ceil(issue.population * policy.issue_quorum_num / policy.issue_quorum_den) 93.134 + } 93.135 + end 93.136 + end 93.137 + if issue.accepted then 93.138 + ui.field.timestamp{ label = _"Accepted at", name = "accepted" } 93.139 + end 93.140 + ui.field.text{ label = _"Discussion time", value = format.interval_text(issue.discussion_time_text) } 93.141 + if issue.half_frozen then 93.142 + ui.field.timestamp{ label = _"Half frozen at", name = "half_frozen" } 93.143 + end 93.144 + ui.field.text{ label = _"Verification time", value = format.interval_text(issue.verification_time_text) } 93.145 + ui.field.text{ 93.146 + label = _"Initiative quorum", 93.147 + value = format.percentage(policy.initiative_quorum_num / policy.initiative_quorum_den) 93.148 + } 93.149 + if issue.population then 93.150 + ui.field.text{ 93.151 + label = _"Currently required", 93.152 + value = math.ceil(issue.population * (issue.policy.initiative_quorum_num / issue.policy.initiative_quorum_den)), 93.153 + } 93.154 + end 93.155 + if issue.fully_frozen then 93.156 + ui.field.timestamp{ label = _"Fully frozen at", name = "fully_frozen" } 93.157 + end 93.158 + ui.field.text{ label = _"Voting time", value = format.interval_text(issue.voting_time_text) } 93.159 + if issue.closed then 93.160 + ui.field.timestamp{ label = _"Closed", name = "closed" } 93.161 + end 93.162 + end 93.163 + } 93.164 93.165 +end ) 93.166 +
94.1 --- a/app/main/member/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 94.2 +++ b/app/main/member/_action/update.lua Thu Jul 10 01:19:48 2014 +0200 94.3 @@ -23,11 +23,11 @@ 94.4 end 94.5 94.6 if not config.locked_profile_fields.statement then 94.7 - local formatting_engine = param.get("formatting_engine") 94.8 + local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine 94.9 94.10 local formatting_engine_valid = false 94.11 - for fe, dummy in pairs(config.formatting_engine_executeables) do 94.12 - if formatting_engine == fe then 94.13 + for i, fe in pairs(config.formatting_engines) do 94.14 + if formatting_engine == fe.id then 94.15 formatting_engine_valid = true 94.16 end 94.17 end
95.1 --- a/app/main/member/_event_list.lua Thu Jul 10 01:02:43 2014 +0200 95.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 95.3 @@ -1,31 +0,0 @@ 95.4 -local member = param.get("member", "table") 95.5 -local events = param.get_all_cgi()["events"] or "personal" 95.6 - 95.7 -ui.container{ attr = { class = "ui_filter" }, content = function() 95.8 - ui.container{ attr = { class = "ui_filter_head" }, content = function() 95.9 - 95.10 - ui.link{ 95.11 - attr = { class = events == "personal" and "ui_tabs_link active" or nil }, 95.12 - text = _"My areas and issues", 95.13 - module = "index", view = "index", params = { tab = "timeline", events = "personal" } 95.14 - } 95.15 - 95.16 - slot.put(" ") 95.17 - 95.18 - ui.link{ 95.19 - attr = { class = events == "global" and "active" or nil }, 95.20 - text = _"Everything", 95.21 - module = "index", view = "index", params = { tab = "timeline", events = "global" } 95.22 - } 95.23 - end } 95.24 -end } 95.25 - 95.26 -if events == "personal" then 95.27 - execute.view{ 95.28 - module = "event", view = "_list" 95.29 - } 95.30 -elseif events == "global" then 95.31 - execute.view{ 95.32 - module = "event", view = "_list", params = { global = true } 95.33 - } 95.34 -end
96.1 --- a/app/main/member/_list.lua Thu Jul 10 01:02:43 2014 +0200 96.2 +++ b/app/main/member/_list.lua Thu Jul 10 01:19:48 2014 +0200 96.3 @@ -6,16 +6,20 @@ 96.4 local trustee = param.get("trustee", "table") 96.5 local initiator = param.get("initiator", "table") 96.6 local for_votes = param.get("for_votes", atom.boolean) 96.7 +local no_filter = param.get ( "no_filter", atom.boolean ) 96.8 +local no_paginate = param.get ( "no_paginate", atom.boolean ) 96.9 96.10 local paginator_name = param.get("paginator_name") 96.11 96.12 +local member_class = param.get("member_class") 96.13 + 96.14 if initiative or issue then 96.15 if for_votes then 96.16 members_selector:left_join("delegating_voter", "_member_list__delegating_voter", { "_member_list__delegating_voter.issue_id = issue.id AND _member_list__delegating_voter.member_id = ?", app.session.member_id }) 96.17 - members_selector:add_field("_member_list__delegating_voter.delegate_member_ids", "delegate_member_ids") 96.18 + members_selector:add_field("member.id = ANY(_member_list__delegating_voter.delegate_member_ids)", "in_delegation_chain") 96.19 else 96.20 members_selector:left_join("delegating_interest_snapshot", "_member_list__delegating_interest", { "_member_list__delegating_interest.event = issue.latest_snapshot_event AND _member_list__delegating_interest.issue_id = issue.id AND _member_list__delegating_interest.member_id = ?", app.session.member_id }) 96.21 - members_selector:add_field("_member_list__delegating_interest.delegate_member_ids", "delegate_member_ids") 96.22 + members_selector:add_field("member.id = ANY(_member_list__delegating_interest.delegate_member_ids)", "in_delegation_chain") 96.23 end 96.24 end 96.25 96.26 @@ -23,9 +27,11 @@ 96.27 96.28 local filter = { name = "member_list" } 96.29 96.30 -if issue or initiative then 96.31 -end 96.32 - 96.33 +filter[#filter+1] = { 96.34 + name = "last_activity", 96.35 + label = _"Latest activity", 96.36 + selector_modifier = function(selector) selector:add_order_by("last_login DESC NULLS LAST, id DESC") end 96.37 +} 96.38 filter[#filter+1] = { 96.39 name = "newest", 96.40 label = _"Newest", 96.41 @@ -48,9 +54,8 @@ 96.42 selector_modifier = function(selector) selector:add_order_by("name DESC") end 96.43 } 96.44 96.45 -local ui_filters = ui.filters 96.46 if issue or initiative then 96.47 - ui_filters = function(args) args.content() end 96.48 + no_filter = true 96.49 if for_votes then 96.50 members_selector:add_order_by("voter_weight DESC, name, id") 96.51 else 96.52 @@ -58,27 +63,30 @@ 96.53 end 96.54 end 96.55 96.56 -ui_filters{ 96.57 - label = _"Change order", 96.58 - selector = members_selector, 96.59 - filter, 96.60 - content = function() 96.61 - ui.paginate{ 96.62 - name = paginator_name, 96.63 - anchor = paginator_name, 96.64 - selector = members_selector, 96.65 - per_page = 50, 96.66 - content = function() 96.67 - ui.container{ 96.68 - attr = { class = "member_list" }, 96.69 - content = function() 96.70 - local members = members_selector:exec() 96.71 96.72 - for i, member in ipairs(members) do 96.73 +function list_members() 96.74 + local ui_paginate = ui.paginate 96.75 + if no_paginate then 96.76 + ui_paginate = function (args) args.content() end 96.77 + end 96.78 + ui_paginate{ 96.79 + name = paginator_name, 96.80 + anchor = paginator_name, 96.81 + selector = members_selector, 96.82 + per_page = 50, 96.83 + content = function() 96.84 + ui.container{ 96.85 + attr = { class = "member_list" }, 96.86 + content = function() 96.87 + local members = members_selector:exec() 96.88 + 96.89 + for i, member in ipairs(members) do 96.90 + ui.sectionRow( function() 96.91 execute.view{ 96.92 module = "member", 96.93 view = "_show_thumb", 96.94 params = { 96.95 + class = member_class, 96.96 member = member, 96.97 initiative = initiative, 96.98 issue = issue, 96.99 @@ -86,13 +94,24 @@ 96.100 initiator = initiator 96.101 } 96.102 } 96.103 - end 96.104 + end ) 96.105 + end 96.106 96.107 96.108 - end 96.109 - } 96.110 - slot.put('<br style="clear: left;" />') 96.111 - end 96.112 - } 96.113 - end 96.114 -} 96.115 + end 96.116 + } 96.117 + end 96.118 + } 96.119 +end 96.120 + 96.121 + 96.122 +if no_filter then 96.123 + list_members() 96.124 +else 96.125 + ui.filters { 96.126 + label = _"Change order", 96.127 + selector = members_selector, 96.128 + content = list_members, 96.129 + filter 96.130 + } 96.131 +end 96.132 \ No newline at end of file
97.1 --- a/app/main/member/_profile.lua Thu Jul 10 01:02:43 2014 +0200 97.2 +++ b/app/main/member/_profile.lua Thu Jul 10 01:19:48 2014 +0200 97.3 @@ -1,6 +1,6 @@ 97.4 local member = param.get("member", "table") 97.5 97.6 -local include_private_data = param.get("include_private_data", atom.boolean) 97.7 +local for_registration = param.get("for_registration", atom.boolean) 97.8 97.9 if not member then 97.10 local member_id = param.get("member_id", atom.integer) 97.11 @@ -10,34 +10,23 @@ 97.12 end 97.13 97.14 ui.form{ 97.15 - attr = { class = "member_statement member vertical" }, 97.16 + attr = { class = "form" }, 97.17 record = member, 97.18 readonly = true, 97.19 content = function() 97.20 97.21 - slot.put("<br />") 97.22 - 97.23 - ui.container{ 97.24 - attr = { class = "right" }, 97.25 - content = function() 97.26 - 97.27 - execute.view{ 97.28 - module = "member_image", 97.29 - view = "_show", 97.30 - params = { 97.31 - member = member, 97.32 - image_type = "photo" 97.33 + if not for_registration then 97.34 + ui.container { attr = { class = "member_photo" }, content = function() 97.35 + execute.view{ 97.36 + module = "member_image", 97.37 + view = "_show", 97.38 + params = { 97.39 + member = member, 97.40 + image_type = "photo" 97.41 + } 97.42 } 97.43 - } 97.44 - 97.45 - ui.container{ 97.46 - attr = { class = "contact_data" }, 97.47 - content = function() 97.48 - end 97.49 - } 97.50 - 97.51 - end 97.52 - } 97.53 + end } 97.54 + end 97.55 97.56 if member.identification then 97.57 ui.field.text{ label = _"Identification", name = "identification" } 97.58 @@ -45,8 +34,11 @@ 97.59 if member.name then 97.60 ui.field.text{ label = _"Screen name", name = "name" } 97.61 end 97.62 - if include_private_data and member.login then 97.63 + if for_registration and member.login then 97.64 ui.field.text{ label = _"Login name", name = "login" } 97.65 + end 97.66 + 97.67 + if for_registration and member.notify_email then 97.68 ui.field.text{ label = _"Notification email", name = "notify_email" } 97.69 end 97.70
98.1 --- a/app/main/member/_show.lua Thu Jul 10 01:02:43 2014 +0200 98.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 98.3 @@ -1,108 +0,0 @@ 98.4 -local member = param.get("member", "table") 98.5 - 98.6 -local tabs = { 98.7 - module = "member", 98.8 - view = "show_tab", 98.9 - static_params = { 98.10 - member_id = member.id 98.11 - } 98.12 -} 98.13 - 98.14 -tabs[#tabs+1] = { 98.15 - name = "profile", 98.16 - label = _"Profile", 98.17 - icon = { static = "icons/16/application_form.png" }, 98.18 - module = "member", 98.19 - view = "_profile", 98.20 - params = { member = member }, 98.21 -} 98.22 - 98.23 -local areas_selector = member:get_reference_selector("areas") 98.24 -tabs[#tabs+1] = { 98.25 - name = "areas", 98.26 - label = _"Units and areas", 98.27 - icon = { static = "icons/16/package.png" }, 98.28 - module = "index", 98.29 - view = "_member_home", 98.30 - params = { areas_selector = areas_selector, member = member, for_member = true }, 98.31 -} 98.32 - 98.33 -tabs[#tabs+1] = { 98.34 - name = "timeline", 98.35 - label = _"Latest events", 98.36 - module = "event", 98.37 - view = "_list", 98.38 - params = { for_member = member } 98.39 -} 98.40 - 98.41 -tabs[#tabs+1] = { 98.42 - name = "open", 98.43 - label = _"Open issues", 98.44 - module = "issue", 98.45 - view = "_list", 98.46 - link_params = { 98.47 - filter_interest = "issue", 98.48 - }, 98.49 - params = { 98.50 - for_state = "open", 98.51 - for_member = member, 98.52 - issues_selector = Issue:new_selector() 98.53 - :add_where("issue.closed ISNULL") 98.54 - :add_order_by("coalesce(issue.fully_frozen + issue.voting_time, issue.half_frozen + issue.verification_time, issue.accepted + issue.discussion_time, issue.created + issue.admission_time) - now()") 98.55 - } 98.56 -} 98.57 - 98.58 -tabs[#tabs+1] = { 98.59 - name = "closed", 98.60 - label = _"Closed issues", 98.61 - module = "issue", 98.62 - view = "_list", 98.63 - link_params = { 98.64 - filter_interest = "issue", 98.65 - }, 98.66 - params = { 98.67 - for_state = "closed", 98.68 - for_member = member, 98.69 - issues_selector = Issue:new_selector() 98.70 - :add_where("issue.closed NOTNULL") 98.71 - :add_order_by("issue.closed DESC") 98.72 - 98.73 - } 98.74 -} 98.75 - 98.76 - 98.77 -local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations") 98.78 - :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") 98.79 - :add_where("_member_showtab_issue.closed ISNULL") 98.80 -tabs[#tabs+1] = { 98.81 - name = "outgoing_delegations", 98.82 - label = _"Outgoing delegations" .. " (" .. tostring(outgoing_delegations_selector:count()) .. ")", 98.83 - icon = { static = "icons/16/table_go.png" }, 98.84 - module = "delegation", 98.85 - view = "_list", 98.86 - params = { delegations_selector = outgoing_delegations_selector, outgoing = true }, 98.87 -} 98.88 - 98.89 -local incoming_delegations_selector = member:get_reference_selector("incoming_delegations") 98.90 - :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id") 98.91 - :add_where("_member_showtab_issue.closed ISNULL") 98.92 -tabs[#tabs+1] = { 98.93 - name = "incoming_delegations", 98.94 - label = _"Incoming delegations" .. " (" .. tostring(incoming_delegations_selector:count()) .. ")", 98.95 - icon = { static = "icons/16/table_go.png" }, 98.96 - module = "delegation", 98.97 - view = "_list", 98.98 - params = { delegations_selector = incoming_delegations_selector, incoming = true }, 98.99 -} 98.100 - 98.101 -local contacts_selector = member:get_reference_selector("saved_members"):add_where("public") 98.102 -tabs[#tabs+1] = { 98.103 - name = "contacts", 98.104 - label = _"Contacts" .. " (" .. tostring(contacts_selector:count()) .. ")", 98.105 - icon = { static = "icons/16/book_edit.png" }, 98.106 - module = "member", 98.107 - view = "_list", 98.108 - params = { members_selector = contacts_selector }, 98.109 -} 98.110 - 98.111 -ui.tabs(tabs)
99.1 --- a/app/main/member/_show_thumb.lua Thu Jul 10 01:02:43 2014 +0200 99.2 +++ b/app/main/member/_show_thumb.lua Thu Jul 10 01:19:48 2014 +0200 99.3 @@ -5,6 +5,8 @@ 99.4 local initiative = param.get("initiative", "table") 99.5 local trustee = param.get("trustee", "table") 99.6 99.7 +local class = param.get("class") 99.8 + 99.9 local name_html 99.10 if member.name_highlighted then 99.11 name_html = encode.highlight(member.name_highlighted) 99.12 @@ -21,15 +23,19 @@ 99.13 container_class = container_class .. " not_informed" 99.14 end 99.15 99.16 -local in_delegation_chain = false 99.17 -if member.delegate_member_ids then 99.18 +if class then 99.19 + container_class = container_class .. " " .. class 99.20 +end 99.21 + 99.22 +local in_delegation_chain = member.in_delegation_chain 99.23 +--[[if member.delegate_member_ids then 99.24 for member_id in member.delegate_member_ids:gmatch("(%w+)") do 99.25 if tonumber(member_id) == member.id then 99.26 in_delegation_chain = true 99.27 end 99.28 end 99.29 end 99.30 - 99.31 +--]] 99.32 if in_delegation_chain or ((issue or initiative) and member.id == app.session.member_id) then 99.33 container_class = container_class .. " in_delegation_chain" 99.34 end 99.35 @@ -37,140 +43,165 @@ 99.36 ui.container{ 99.37 attr = { class = container_class }, 99.38 content = function() 99.39 - ui.container{ 99.40 - attr = { class = "flags" }, 99.41 - content = function() 99.42 + 99.43 + local function doit() 99.44 + execute.view{ 99.45 + module = "member_image", 99.46 + view = "_show", 99.47 + params = { 99.48 + member = member, 99.49 + image_type = "avatar", 99.50 + show_dummy = true 99.51 + } 99.52 + } 99.53 + ui.tag{ 99.54 + attr = { class = "member_name" }, 99.55 + content = function() slot.put(name_html) end 99.56 + } 99.57 + end 99.58 + 99.59 + if app.session:has_access("everything") then 99.60 + ui.link{ 99.61 + attr = { title = _"Show member" }, 99.62 + module = "member", 99.63 + view = "show", 99.64 + id = member.id, 99.65 + content = doit 99.66 + } 99.67 + else 99.68 + ui.tag{ content = doit } 99.69 + end 99.70 99.71 - if not member.active then 99.72 - local text = _"inactive" 99.73 - ui.tag{ content = text } 99.74 + if member.grade then 99.75 + slot.put ( " " ) 99.76 + ui.link{ 99.77 + module = "vote", 99.78 + view = "list", 99.79 + params = { 99.80 + issue_id = initiative.issue.id, 99.81 + member_id = member.id, 99.82 + }, 99.83 + content = function() 99.84 + if member.grade > 0 then 99.85 + ui.image{ 99.86 + attr = { 99.87 + alt = _"Voted yes", 99.88 + title = _"Voted yes", 99.89 + class = "icon24 right" 99.90 + }, 99.91 + static = "icons/32/support_satisfied.png" 99.92 + } 99.93 + elseif member.grade < 0 then 99.94 + ui.image{ 99.95 + attr = { 99.96 + alt = _"Voted no", 99.97 + title = _"Voted no", 99.98 + class = "icon24 right" 99.99 + }, 99.100 + static = "icons/32/voted_no.png" 99.101 + } 99.102 + else 99.103 + ui.image{ 99.104 + attr = { 99.105 + alt = _"Abstention", 99.106 + title = _"Abstention", 99.107 + class = "icon24 right" 99.108 + }, 99.109 + static = "icons/16/bullet_yellow.png" 99.110 + } 99.111 + end 99.112 + end 99.113 + } 99.114 + end 99.115 + 99.116 + if (member.voter_comment) then 99.117 + ui.link{ 99.118 + module = "vote", 99.119 + view = "list", 99.120 + params = { 99.121 + issue_id = issue.id, 99.122 + member_id = member.id, 99.123 + }, 99.124 + content = function() 99.125 ui.image{ 99.126 - attr = { alt = text, title = text }, 99.127 - static = "icons/16/cross.png" 99.128 - } 99.129 - end 99.130 - 99.131 - if member.grade then 99.132 - ui.link{ 99.133 - module = "vote", 99.134 - view = "list", 99.135 - params = { 99.136 - issue_id = initiative.issue.id, 99.137 - member_id = member.id, 99.138 + attr = { 99.139 + alt = _"Voting comment available", 99.140 + title = _"Voting comment available", 99.141 + class = "icon24 right" 99.142 }, 99.143 - content = function() 99.144 - if (member.voter_comment) then 99.145 - ui.image{ 99.146 - attr = { 99.147 - alt = _"Voting comment available", 99.148 - title = _"Voting comment available" 99.149 - }, 99.150 - static = "icons/16/comment.png" 99.151 - } 99.152 - end 99.153 - 99.154 - if member.grade > 0 then 99.155 - ui.image{ 99.156 - attr = { 99.157 - alt = _"Voted yes", 99.158 - title = _"Voted yes" 99.159 - }, 99.160 - static = "icons/16/thumb_up_green.png" 99.161 - } 99.162 - elseif member.grade < 0 then 99.163 - ui.image{ 99.164 - attr = { 99.165 - alt = _"Voted no", 99.166 - title = _"Voted no" 99.167 - }, 99.168 - static = "icons/16/thumb_down_red.png" 99.169 - } 99.170 - else 99.171 - ui.image{ 99.172 - attr = { 99.173 - alt = _"Abstention", 99.174 - title = _"Abstention" 99.175 - }, 99.176 - static = "icons/16/bullet_yellow.png" 99.177 - } 99.178 - end 99.179 - end 99.180 + static = "icons/16/comment.png" 99.181 } 99.182 end 99.183 + } 99.184 + end 99.185 99.186 - local weight = 0 99.187 - if member.weight then 99.188 - weight = member.weight 99.189 - end 99.190 - if member.voter_weight then 99.191 - weight = member.voter_weight 99.192 - end 99.193 - if (issue or initiative) and weight > 1 then 99.194 - local module 99.195 - if issue then 99.196 - module = "interest" 99.197 - elseif initiative then 99.198 - if member.voter_weight then 99.199 - module = "vote" 99.200 - else 99.201 - module = "supporter" 99.202 - end 99.203 - end 99.204 - ui.link{ 99.205 - attr = { 99.206 - class = in_delegation_chain and "in_delegation_chain" or nil, 99.207 - title = _"Number of incoming delegations, follow link to see more details" 99.208 - }, 99.209 - content = _("+ #{weight}", { weight = weight - 1 }), 99.210 - module = module, 99.211 - view = "show_incoming", 99.212 - params = { 99.213 - member_id = member.id, 99.214 - initiative_id = initiative and initiative.id or nil, 99.215 - issue_id = issue and issue.id or nil 99.216 - } 99.217 - } 99.218 - end 99.219 + local weight = 0 99.220 + if member.weight then 99.221 + weight = member.weight 99.222 + end 99.223 + if member.voter_weight then 99.224 + weight = member.voter_weight 99.225 + end 99.226 + 99.227 + if (issue or initiative) and weight > 1 then 99.228 + local module = "interest" 99.229 + if member.voter_weight then 99.230 + module = "vote" 99.231 + end 99.232 99.233 - if initiator and initiator.accepted then 99.234 - if member.accepted == nil then 99.235 - slot.put(_"Invited") 99.236 - elseif member.accepted == false then 99.237 - slot.put(_"Rejected") 99.238 - end 99.239 - end 99.240 - 99.241 - if member.is_informed == false then 99.242 - local text = _"Member has not approved latest draft" 99.243 - ui.image{ 99.244 - attr = { alt = text, title = text }, 99.245 - static = "icons/16/help_yellow.png" 99.246 - } 99.247 - end 99.248 - 99.249 + slot.put ( " " ) 99.250 + ui.link{ 99.251 + attr = { 99.252 + class = in_delegation_chain and "in_delegation_chain" or nil, 99.253 + title = _"Number of incoming delegations, follow link to see more details" 99.254 + }, 99.255 + content = _("+ #{weight}", { weight = weight - 1 }), 99.256 + module = module, 99.257 + view = "show_incoming", 99.258 + params = { 99.259 + member_id = member.id, 99.260 + initiative_id = initiative and initiative.id or nil, 99.261 + issue_id = issue and issue.id or nil 99.262 + } 99.263 + } 99.264 + end 99.265 + 99.266 + if member.supporter then 99.267 + slot.put ( " " ) 99.268 + if member.supporter_satisfied then 99.269 + local text = _"supporter" 99.270 + ui.image{ attr = { class = "icon24 right", alt = text, title = text }, static = "icons/32/support_satisfied.png" } 99.271 + else 99.272 + local text = _"supporter with restricting suggestions" 99.273 + ui.image{ attr = { class = "icon24 right", alt = text, title = text }, static = "icons/32/support_unsatisfied.png" } 99.274 end 99.275 - } 99.276 + end 99.277 99.278 - ui.link{ 99.279 - attr = { title = _"Show member" }, 99.280 - module = "member", 99.281 - view = "show", 99.282 - id = member.id, 99.283 - content = function() 99.284 - execute.view{ 99.285 - module = "member_image", 99.286 - view = "_show", 99.287 - params = { 99.288 - member = member, 99.289 - image_type = "avatar", 99.290 - show_dummy = true 99.291 - } 99.292 - } 99.293 - ui.container{ 99.294 - attr = { class = "member_name" }, 99.295 - content = function() slot.put(name_html) end 99.296 - } 99.297 + if not member.active then 99.298 + slot.put ( " " ) 99.299 + local text = _"member inactive" 99.300 + ui.image{ 99.301 + attr = { alt = text, title = text }, 99.302 + static = "icons/16/cross.png" 99.303 + } 99.304 + ui.tag{ content = _"inactive" } 99.305 + end 99.306 + 99.307 + if initiator and initiator.accepted then 99.308 + if member.accepted == nil then 99.309 + slot.put(_"Invited") 99.310 + elseif member.accepted == false then 99.311 + slot.put(_"Rejected") 99.312 end 99.313 - } 99.314 + end 99.315 + 99.316 + if member.is_informed == false then 99.317 + local text = _"Member has not approved latest draft" 99.318 + ui.image{ 99.319 + attr = { alt = text, title = text }, 99.320 + static = "icons/16/help_yellow.png" 99.321 + } 99.322 + end 99.323 + 99.324 end 99.325 }
100.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 100.2 +++ b/app/main/member/_sidebar_contacts.lua Thu Jul 10 01:19:48 2014 +0200 100.3 @@ -0,0 +1,86 @@ 100.4 +local member = param.get("member", "table") 100.5 + 100.6 +local public_contacts_selector = Contact:build_selector{ 100.7 + public = true, 100.8 + member_id = member.id, 100.9 + order = "name" 100.10 +} 100.11 + 100.12 +local private_contacts_selector = Contact:build_selector{ 100.13 + public = false, 100.14 + member_id = member.id, 100.15 + order = "name" 100.16 +} 100.17 + 100.18 +ui.sidebar( "tab-members", function() 100.19 + 100.20 + ui.sidebarHead( function() 100.21 + ui.heading { level = 2, content = _"Published contacts" } 100.22 + end ) 100.23 + 100.24 + --ui.sidebarSection( function() 100.25 + 100.26 + if public_contacts_selector:count() == 0 then 100.27 + ui.sidebarSection( function() 100.28 + ui.field.text{ value = _"No published contacts" } 100.29 + end ) 100.30 + else 100.31 + ui.paginate{ 100.32 + selector = public_contacts_selector, 100.33 + name = "contacts", 100.34 + content = function() 100.35 + local contacts = public_contacts_selector:exec() 100.36 + for i, contact in ipairs(contacts) do 100.37 + ui.sidebarSection( "sidebarRowNarrow", function() 100.38 + execute.view{ module = "member_image", view = "_show", params = { 100.39 + member_id = contact.other_member.id, class = "micro_avatar", 100.40 + popup_text = contact.other_member.name, 100.41 + image_type = "avatar", show_dummy = true, 100.42 + } } 100.43 + slot.put(" ") 100.44 + ui.link{ 100.45 + content = contact.other_member.name, 100.46 + module = "member", 100.47 + view = "show", 100.48 + id = contact.other_member.id 100.49 + } 100.50 + end ) 100.51 + end 100.52 + end 100.53 + } 100.54 + end 100.55 + --end ) 100.56 + 100.57 + 100.58 + if member.id == app.session.member.id and private_contacts_selector:count() > 0 then 100.59 + 100.60 + ui.sidebarHead( function() 100.61 + ui.heading { level = 2, content = _"Private contacts" } 100.62 + end ) 100.63 + 100.64 + ui.paginate{ 100.65 + selector = private_contacts_selector, 100.66 + name = "contacts", 100.67 + content = function() 100.68 + local contacts = private_contacts_selector:exec() 100.69 + for i, contact in ipairs(contacts) do 100.70 + ui.sidebarSection( "sidebarRowNarrow", function() 100.71 + execute.view{ module = "member_image", view = "_show", params = { 100.72 + member_id = contact.other_member.id, class = "micro_avatar", 100.73 + popup_text = contact.other_member.name, 100.74 + image_type = "avatar", show_dummy = true, 100.75 + } } 100.76 + slot.put(" ") 100.77 + ui.link{ 100.78 + content = contact.other_member.name, 100.79 + module = "member", 100.80 + view = "show", 100.81 + id = contact.other_member.id 100.82 + } 100.83 + end ) 100.84 + end 100.85 + end 100.86 + } 100.87 + 100.88 + end 100.89 +end ) 100.90 \ No newline at end of file
101.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 101.2 +++ b/app/main/member/_sidebar_whatcanido.lua Thu Jul 10 01:19:48 2014 +0200 101.3 @@ -0,0 +1,326 @@ 101.4 +local member = param.get("member", "table") 101.5 + 101.6 +ui.sidebar( "tab-whatcanido", function() 101.7 + 101.8 + if not member.active then 101.9 + ui.container{ attr = { class = "sidebarSection" }, content = function() 101.10 + slot.put(" · ") 101.11 + ui.tag{ 101.12 + attr = { class = "interest deactivated_member_info" }, 101.13 + content = _"This member is inactive" 101.14 + } 101.15 + end } 101.16 + end 101.17 + 101.18 + if member.locked then 101.19 + ui.container{ attr = { class = "sidebarSection" }, content = function() 101.20 + slot.put(" · ") 101.21 + ui.tag{ 101.22 + attr = { class = "interest deactivated_member_info" }, 101.23 + content = _"This member is locked" 101.24 + } 101.25 + end } 101.26 + end 101.27 + 101.28 + 101.29 + ui.sidebarHeadWhatCanIDo() 101.30 + 101.31 + if member.id == app.session.member_id and not app.session.needs_delegation_check then 101.32 + ui.sidebarSection( function() 101.33 + ui.heading { level = 3, content = _"I want to customize my profile" } 101.34 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 101.35 + ui.tag{ tag = "li", content = function() 101.36 + ui.link{ 101.37 + content = _"edit profile data", 101.38 + module = "member", 101.39 + view = "edit" 101.40 + } 101.41 + end } 101.42 + ui.tag{ tag = "li", content = function() 101.43 + ui.link{ 101.44 + content = _"change avatar/photo", 101.45 + module = "member", 101.46 + view = "edit_images" 101.47 + } 101.48 + end } 101.49 + end } 101.50 + end ) 101.51 + --[[ 101.52 + ui.sidebarSection( function() 101.53 + ui.heading { level = 3, content = _"I want to manage my saved contacts" } 101.54 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 101.55 + ui.tag{ tag = "li", content = function() 101.56 + 101.57 + ui.link{ 101.58 + content = _"show saved contacts", 101.59 + module = 'contact', 101.60 + view = 'list' 101.61 + } 101.62 + 101.63 + end } 101.64 + end } 101.65 + end ) 101.66 + --]] 101.67 + 101.68 + ui.sidebarSection( function() 101.69 + 101.70 + ui.heading { level = 3, content = _"I want to change account settings" } 101.71 + 101.72 + local pages = {} 101.73 + 101.74 + pages[#pages+1] = { view = "settings_notification", text = _"notification settings" } 101.75 + if not config.locked_profile_fields.notify_email then 101.76 + pages[#pages+1] = { view = "settings_email", text = _"change your notification email address" } 101.77 + end 101.78 + if not config.locked_profile_fields.name then 101.79 + pages[#pages+1] = { view = "settings_name", text = _"change your screen name" } 101.80 + end 101.81 + if not config.locked_profile_fields.login then 101.82 + pages[#pages+1] = { view = "settings_login", text = _"change your login" } 101.83 + end 101.84 + pages[#pages+1] = { view = "settings_password", text = _"change your password" } 101.85 + pages[#pages+1] = { view = "developer_settings", text = _"developer settings" } 101.86 + 101.87 + if config.download_dir then 101.88 + pages[#pages+1] = { module = "index", view = "download", text = _"database download" } 101.89 + end 101.90 + 101.91 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 101.92 + for i, page in ipairs(pages) do 101.93 + ui.tag{ tag = "li", content = function() 101.94 + ui.link{ 101.95 + module = page.module or "member", 101.96 + view = page.view, 101.97 + text = page.text 101.98 + } 101.99 + end } 101.100 + end 101.101 + end } 101.102 + end ) 101.103 + 101.104 + ui.sidebarSection( function() 101.105 + ui.heading { level = 3, content = _"I want to logout" } 101.106 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 101.107 + ui.tag{ tag = "li", content = function() 101.108 + ui.link{ 101.109 + text = _"logout", 101.110 + module = 'index', 101.111 + action = 'logout', 101.112 + routing = { 101.113 + default = { 101.114 + mode = "redirect", 101.115 + module = "index", 101.116 + view = "index" 101.117 + } 101.118 + } 101.119 + } 101.120 + end } 101.121 + end } 101.122 + end ) 101.123 + 101.124 + ui.sidebarSection( function() 101.125 + ui.heading { level = 3, content = _"I want to change the interface language" } 101.126 + ui.tag{ tag = "ul", attr = { class = "ul" }, content = function() 101.127 + for i, lang in ipairs(config.enabled_languages) do 101.128 + 101.129 + local langcode 101.130 + 101.131 + locale.do_with({ lang = lang }, function() 101.132 + langcode = _("[Name of Language]") 101.133 + end) 101.134 + 101.135 + ui.tag{ tag = "li", content = function() 101.136 + ui.link{ 101.137 + content = _('Select language "#{langcode}"', { langcode = langcode }), 101.138 + module = "index", 101.139 + action = "set_lang", 101.140 + params = { lang = lang }, 101.141 + routing = { 101.142 + default = { 101.143 + mode = "redirect", 101.144 + module = request.get_module(), 101.145 + view = request.get_view(), 101.146 + id = param.get_id_cgi(), 101.147 + params = param.get_all_cgi() 101.148 + } 101.149 + } 101.150 + } 101.151 + end } 101.152 + end 101.153 + end } 101.154 + end ) 101.155 + elseif app.session.member_id and not (member.id == app.session.member.id) then 101.156 + 101.157 + ui.sidebarSection( function () 101.158 + 101.159 + local contact = Contact:by_pk(app.session.member.id, member.id) 101.160 + if not contact then 101.161 + ui.heading { level = 3, content = _"I want to save this member as contact (i.e. to use as delegatee)" } 101.162 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 101.163 + ui.tag { tag = "li", content = function () 101.164 + ui.link{ 101.165 + text = _"add to my list of public contacts", 101.166 + module = "contact", 101.167 + action = "add_member", 101.168 + id = member.id, 101.169 + params = { public = true }, 101.170 + routing = { 101.171 + default = { 101.172 + mode = "redirect", 101.173 + module = request.get_module(), 101.174 + view = request.get_view(), 101.175 + id = param.get_id_cgi(), 101.176 + params = param.get_all_cgi() 101.177 + } 101.178 + } 101.179 + } 101.180 + end } 101.181 + ui.tag { tag = "li", content = function () 101.182 + ui.link{ 101.183 + text = _"add to my list of private contacts", 101.184 + module = "contact", 101.185 + action = "add_member", 101.186 + id = member.id, 101.187 + routing = { 101.188 + default = { 101.189 + mode = "redirect", 101.190 + module = request.get_module(), 101.191 + view = request.get_view(), 101.192 + id = param.get_id_cgi(), 101.193 + params = param.get_all_cgi() 101.194 + } 101.195 + } 101.196 + } 101.197 + end } 101.198 + end } 101.199 + elseif contact.public then 101.200 + ui.heading { level = 3, content = _"You saved this member as contact (i.e. to use as delegatee) and others can see it" } 101.201 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 101.202 + ui.tag { tag = "li", content = function () 101.203 + ui.link{ 101.204 + text = _"make this contact private", 101.205 + module = "contact", 101.206 + action = "add_member", 101.207 + id = contact.other_member_id, 101.208 + params = { public = false }, 101.209 + routing = { 101.210 + default = { 101.211 + mode = "redirect", 101.212 + module = request.get_module(), 101.213 + view = request.get_view(), 101.214 + id = param.get_id_cgi(), 101.215 + params = param.get_all_cgi() 101.216 + } 101.217 + } 101.218 + } 101.219 + end } 101.220 + ui.tag { tag = "li", content = function () 101.221 + ui.link{ 101.222 + text = _"remove from my contact list", 101.223 + module = "contact", 101.224 + action = "remove_member", 101.225 + id = contact.other_member_id, 101.226 + routing = { 101.227 + default = { 101.228 + mode = "redirect", 101.229 + module = request.get_module(), 101.230 + view = request.get_view(), 101.231 + id = param.get_id_cgi(), 101.232 + params = param.get_all_cgi() 101.233 + } 101.234 + } 101.235 + } 101.236 + end } 101.237 + end } 101.238 + else 101.239 + ui.heading { level = 3, content = _"You saved this member as contact (i.e. to use as delegatee)" } 101.240 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 101.241 + ui.tag { tag = "li", content = function () 101.242 + ui.link{ 101.243 + text = _"make this contact public", 101.244 + module = "contact", 101.245 + action = "add_member", 101.246 + id = contact.other_member_id, 101.247 + params = { public = true }, 101.248 + routing = { 101.249 + default = { 101.250 + mode = "redirect", 101.251 + module = request.get_module(), 101.252 + view = request.get_view(), 101.253 + id = param.get_id_cgi(), 101.254 + params = param.get_all_cgi() 101.255 + } 101.256 + } 101.257 + } 101.258 + end } 101.259 + ui.tag { tag = "li", content = function () 101.260 + ui.link{ 101.261 + text = _"remove from my contact list", 101.262 + module = "contact", 101.263 + action = "remove_member", 101.264 + id = contact.other_member_id, 101.265 + routing = { 101.266 + default = { 101.267 + mode = "redirect", 101.268 + module = request.get_module(), 101.269 + view = request.get_view(), 101.270 + id = param.get_id_cgi(), 101.271 + params = param.get_all_cgi() 101.272 + } 101.273 + } 101.274 + } 101.275 + end } 101.276 + end } 101.277 + end 101.278 + end ) 101.279 + 101.280 + ui.sidebarSection( function() 101.281 + local ignored_member = IgnoredMember:by_pk(app.session.member.id, member.id) 101.282 + if not ignored_member then 101.283 + ui.heading { level = 3, content = _"I do not like to hear from this member" } 101.284 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 101.285 + ui.tag { tag = "li", content = function () 101.286 + ui.link{ 101.287 + attr = { class = "interest" }, 101.288 + text = _"block this member", 101.289 + module = "member", 101.290 + action = "update_ignore_member", 101.291 + id = member.id, 101.292 + routing = { 101.293 + default = { 101.294 + mode = "redirect", 101.295 + module = request.get_module(), 101.296 + view = request.get_view(), 101.297 + id = param.get_id_cgi(), 101.298 + params = param.get_all_cgi() 101.299 + } 101.300 + } 101.301 + } 101.302 + end } 101.303 + end } 101.304 + else 101.305 + ui.heading { level = 3, content = _"You blocked this member (i.e. you will not be notified about this members actions)" } 101.306 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 101.307 + ui.tag { tag = "li", content = function () 101.308 + ui.link{ 101.309 + text = _"unblock member", 101.310 + module = "member", 101.311 + action = "update_ignore_member", 101.312 + id = member.id, 101.313 + params = { delete = true }, 101.314 + routing = { 101.315 + default = { 101.316 + mode = "redirect", 101.317 + module = request.get_module(), 101.318 + view = request.get_view(), 101.319 + id = param.get_id_cgi(), 101.320 + params = param.get_all_cgi() 101.321 + } 101.322 + } 101.323 + } 101.324 + end } 101.325 + end } 101.326 + end 101.327 + end ) 101.328 + end 101.329 +end ) 101.330 \ No newline at end of file
102.1 --- a/app/main/member/developer_settings.lua Thu Jul 10 01:02:43 2014 +0200 102.2 +++ b/app/main/member/developer_settings.lua Thu Jul 10 01:19:48 2014 +0200 102.3 @@ -1,96 +1,116 @@ 102.4 ui.title(_"Developer settings") 102.5 102.6 +execute.view { 102.7 + module = "member", view = "_sidebar_whatcanido", params = { 102.8 + member = app.session.member 102.9 + } 102.10 +} 102.11 102.12 local setting_key = "liquidfeedback_frontend_developer_features" 102.13 local setting = Setting:by_pk(app.session.member.id, setting_key) 102.14 102.15 -if setting then 102.16 - ui.form{ 102.17 - attr = { class = "vertical" }, 102.18 - module = "member", 102.19 - action = "update_stylesheet_url", 102.20 - routing = { 102.21 - ok = { 102.22 - mode = "redirect", 102.23 - module = "index", 102.24 - view = "index" 102.25 +if true or setting then 102.26 + ui.section( function() 102.27 + ui.sectionHead( function () 102.28 + ui.heading{ content = "CSS development settings" } 102.29 + end ) 102.30 + 102.31 + ui.sectionRow( function() 102.32 + ui.form{ 102.33 + attr = { class = "vertical" }, 102.34 + module = "member", 102.35 + action = "update_stylesheet_url", 102.36 + routing = { 102.37 + ok = { 102.38 + mode = "redirect", 102.39 + module = "member", 102.40 + view = "show", 102.41 + id = app.session.member_id 102.42 + } 102.43 + }, 102.44 + content = function() 102.45 + local setting_key = "liquidfeedback_frontend_stylesheet_url" 102.46 + local setting = Setting:by_pk(app.session.member.id, setting_key) 102.47 + local value = setting and setting.value 102.48 + ui.field.text{ 102.49 + label = "stylesheet URL", 102.50 + name = "stylesheet_url", 102.51 + value = value 102.52 + } 102.53 + ui.submit{ value = _"Set URL" } 102.54 + end 102.55 } 102.56 - }, 102.57 - content = function() 102.58 - local setting_key = "liquidfeedback_frontend_stylesheet_url" 102.59 - local setting = Setting:by_pk(app.session.member.id, setting_key) 102.60 - local value = setting and setting.value 102.61 - ui.field.text{ 102.62 - label = _"Stylesheet URL", 102.63 - name = "stylesheet_url", 102.64 - value = value 102.65 - } 102.66 - ui.submit{ value = _"Set URL" } 102.67 - end 102.68 - } 102.69 + end ) 102.70 + end ) 102.71 end 102.72 102.73 -ui.heading{ content = _"API keys" } 102.74 +ui.section( function() 102.75 + ui.sectionHead( function () 102.76 + ui.heading{ content = "API keys" } 102.77 + end ) 102.78 102.79 -local member_applications = MemberApplication:new_selector() 102.80 - :add_where{ "member_id = ?", app.session.member.id } 102.81 - :add_order_by("name, id") 102.82 - :exec() 102.83 - 102.84 -if #member_applications > 0 then 102.85 + ui.sectionRow( function() 102.86 + local member_applications = MemberApplication:new_selector() 102.87 + :add_where{ "member_id = ?", app.session.member.id } 102.88 + :add_order_by("name, id") 102.89 + :exec() 102.90 + 102.91 + if #member_applications > 0 then 102.92 102.93 - ui.list{ 102.94 - records = member_applications, 102.95 - columns = { 102.96 - { 102.97 - name = "name", 102.98 - label = _"Name" 102.99 - }, 102.100 - { 102.101 - name = "access_level", 102.102 - label = _"Access level" 102.103 - }, 102.104 - { 102.105 - name = "key", 102.106 - label = _"API Key" 102.107 - }, 102.108 - { 102.109 - name = "last_usage", 102.110 - label = "Last usage" 102.111 - }, 102.112 - { 102.113 - content = function(member_application) 102.114 - ui.link{ 102.115 - text = _"Delete", 102.116 - module = "member", action = "update_api_key", id = member_application.id, 102.117 - params = { delete = true }, 102.118 - routing = { 102.119 - default = { 102.120 - mode = "redirect", 102.121 - module = "member", 102.122 - view = "developer_settings" 102.123 + ui.list{ 102.124 + records = member_applications, 102.125 + columns = { 102.126 + { 102.127 + name = "name", 102.128 + label = "Name" 102.129 + }, 102.130 + { 102.131 + name = "access_level", 102.132 + label = "Access level" 102.133 + }, 102.134 + { 102.135 + name = "key", 102.136 + label = "API Key" 102.137 + }, 102.138 + { 102.139 + name = "last_usage", 102.140 + label = "Last usage" 102.141 + }, 102.142 + { 102.143 + content = function(member_application) 102.144 + ui.link{ 102.145 + text = "delete", 102.146 + module = "member", action = "update_api_key", id = member_application.id, 102.147 + params = { delete = true }, 102.148 + routing = { 102.149 + default = { 102.150 + mode = "redirect", 102.151 + module = "member", 102.152 + view = "developer_settings" 102.153 + } 102.154 + } 102.155 } 102.156 - } 102.157 - } 102.158 - end 102.159 - }, 102.160 - } 102.161 - } 102.162 + end 102.163 + }, 102.164 + } 102.165 + } 102.166 102.167 -else 102.168 - 102.169 - slot.put(_"Currently no API key is set.") 102.170 - slot.put(" ") 102.171 - ui.link{ 102.172 - text = _"Generate API key", 102.173 - module = "member", 102.174 - action = "update_api_key", 102.175 - routing = { 102.176 - default = { 102.177 - mode = "redirect", 102.178 + else 102.179 + 102.180 + slot.put(_"Currently no API key is set.") 102.181 + slot.put(" ") 102.182 + ui.link{ 102.183 + text = _"Generate API key", 102.184 module = "member", 102.185 - view = "developer_settings" 102.186 + action = "update_api_key", 102.187 + routing = { 102.188 + default = { 102.189 + mode = "redirect", 102.190 + module = "member", 102.191 + view = "developer_settings" 102.192 + } 102.193 + } 102.194 } 102.195 - } 102.196 - } 102.197 -end 102.198 + end 102.199 + end ) 102.200 +end ) 102.201 \ No newline at end of file
103.1 --- a/app/main/member/edit.lua Thu Jul 10 01:02:43 2014 +0200 103.2 +++ b/app/main/member/edit.lua Thu Jul 10 01:19:48 2014 +0200 103.3 @@ -1,6 +1,10 @@ 103.4 -ui.title(_"Edit my profile") 103.5 +ui.titleMember(_"Edit your profile data") 103.6 103.7 -util.help("member.edit", _"Edit my page") 103.8 +execute.view { 103.9 + module = "member", view = "_sidebar_whatcanido", params = { 103.10 + member = app.session.member 103.11 + } 103.12 +} 103.13 103.14 ui.form{ 103.15 record = app.session.member, 103.16 @@ -16,73 +20,98 @@ 103.17 } 103.18 }, 103.19 content = function() 103.20 - ui.field.text{ label = _"Identification", name = "identification", readonly = true } 103.21 - ui.field.text{ label = _"Organizational unit", name = "organizational_unit", readonly = config.locked_profile_fields.organizational_unit } 103.22 - ui.field.text{ label = _"Internal posts", name = "internal_posts", readonly = config.locked_profile_fields.internal_posts } 103.23 - ui.field.text{ label = _"Real name", name = "realname", readonly = config.locked_profile_fields.realname } 103.24 - ui.field.text{ label = _"Birthday" .. " YYYY-MM-DD ", name = "birthday", attr = { id = "profile_birthday" }, readonly = config.locked_profile_fields.birthday } 103.25 - ui.script{ static = "gregor.js/gregor.js" } 103.26 - util.gregor("profile_birthday", "document.getElementById('timeline_search_date').form.submit();") 103.27 - ui.field.text{ label = _"Address", name = "address", multiline = true, readonly = config.locked_profile_fields.address } 103.28 - ui.field.text{ label = _"email", name = "email", readonly = config.locked_profile_fields.email } 103.29 - ui.field.text{ label = _"xmpp", name = "xmpp_address", readonly = config.locked_profile_fields.xmpp_address } 103.30 - ui.field.text{ label = _"Website", name = "website", readonly = config.locked_profile_fields.website } 103.31 - ui.field.text{ label = _"Phone", name = "phone", readonly = config.locked_profile_fields.phone } 103.32 - ui.field.text{ label = _"Mobile phone", name = "mobile_phone", readonly = config.locked_profile_fields.mobile_phone } 103.33 - ui.field.text{ label = _"Profession", name = "profession", readonly = config.locked_profile_fields.profession } 103.34 - ui.field.text{ label = _"External memberships", name = "external_memberships", multiline = true, readonly = config.locked_profile_fields.external_memberships } 103.35 - ui.field.text{ label = _"External posts", name = "external_posts", multiline = true, readonly = config.locked_profile_fields.external_posts } 103.36 + 103.37 + ui.section( function() 103.38 + 103.39 + ui.sectionHead( function() 103.40 + ui.heading{ level = 1, content = _"Edit your profile data" } 103.41 + end ) 103.42 + 103.43 + ui.sectionRow( _"All fields are optional. Please enter only data which should be published." ) 103.44 + 103.45 + ui.sectionRow( function() 103.46 + 103.47 + ui.field.text{ label = _"Organizational unit", name = "organizational_unit", readonly = config.locked_profile_fields.organizational_unit } 103.48 + ui.field.text{ label = _"Internal posts", name = "internal_posts", readonly = config.locked_profile_fields.internal_posts } 103.49 + ui.field.text{ label = _"Real name", name = "realname", readonly = config.locked_profile_fields.realname } 103.50 + ui.field.text{ label = _"Birthday" .. " YYYY-MM-DD ", name = "birthday", attr = { id = "profile_birthday" }, readonly = config.locked_profile_fields.birthday } 103.51 + ui.script{ static = "gregor.js/gregor.js" } 103.52 + util.gregor("profile_birthday", "document.getElementById('timeline_search_date').form.submit();") 103.53 + ui.field.text{ label = _"Address", name = "address", multiline = true, readonly = config.locked_profile_fields.address } 103.54 + ui.field.text{ label = _"email", name = "email", readonly = config.locked_profile_fields.email } 103.55 + ui.field.text{ label = _"xmpp", name = "xmpp_address", readonly = config.locked_profile_fields.xmpp_address } 103.56 + ui.field.text{ label = _"Website", name = "website", readonly = config.locked_profile_fields.website } 103.57 + ui.field.text{ label = _"Phone", name = "phone", readonly = config.locked_profile_fields.phone } 103.58 + ui.field.text{ label = _"Mobile phone", name = "mobile_phone", readonly = config.locked_profile_fields.mobile_phone } 103.59 + ui.field.text{ label = _"Profession", name = "profession", readonly = config.locked_profile_fields.profession } 103.60 + ui.field.text{ label = _"External memberships", name = "external_memberships", multiline = true, readonly = config.locked_profile_fields.external_memberships } 103.61 + ui.field.text{ label = _"External posts", name = "external_posts", multiline = true, readonly = config.locked_profile_fields.external_posts } 103.62 103.63 - ui.field.select{ 103.64 - label = _"Wiki engine for statement", 103.65 - name = "formatting_engine", 103.66 - foreign_records = { 103.67 - { id = "rocketwiki", name = "RocketWiki" }, 103.68 - { id = "compat", name = _"Traditional wiki syntax" } 103.69 - }, 103.70 - attr = {id = "formatting_engine"}, 103.71 - foreign_id = "id", 103.72 - foreign_name = "name", 103.73 - value = param.get("formatting_engine") 103.74 - } 103.75 - ui.tag{ 103.76 - tag = "div", 103.77 - content = function() 103.78 - ui.tag{ 103.79 - tag = "label", 103.80 - attr = { class = "ui_field_label" }, 103.81 - content = function() slot.put(" ") end, 103.82 + if not config.enforce_formatting_engine then 103.83 + ui.field.select{ 103.84 + label = _"Wiki engine for statement", 103.85 + name = "formatting_engine", 103.86 + foreign_records = config.formatting_engines, 103.87 + attr = {id = "formatting_engine"}, 103.88 + foreign_id = "id", 103.89 + foreign_name = "name", 103.90 + value = param.get("formatting_engine") 103.91 + } 103.92 + ui.tag{ 103.93 + tag = "div", 103.94 + content = function() 103.95 + ui.tag{ 103.96 + tag = "label", 103.97 + attr = { class = "ui_field_label" }, 103.98 + content = function() slot.put(" ") end, 103.99 + } 103.100 + ui.tag{ 103.101 + content = function() 103.102 + ui.link{ 103.103 + text = _"Syntax help", 103.104 + module = "help", 103.105 + view = "show", 103.106 + id = "wikisyntax", 103.107 + attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 103.108 + } 103.109 + slot.put(" ") 103.110 + ui.link{ 103.111 + text = _"(new window)", 103.112 + module = "help", 103.113 + view = "show", 103.114 + id = "wikisyntax", 103.115 + attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 103.116 + } 103.117 + end 103.118 + } 103.119 + end 103.120 + } 103.121 + end 103.122 + ui.field.text{ 103.123 + label = _"Statement", 103.124 + name = "statement", 103.125 + multiline = true, 103.126 + attr = { style = "height: 50ex;" }, 103.127 + value = param.get("statement") 103.128 } 103.129 - ui.tag{ 103.130 - content = function() 103.131 - ui.link{ 103.132 - text = _"Syntax help", 103.133 - module = "help", 103.134 - view = "show", 103.135 - id = "wikisyntax", 103.136 - attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 103.137 - } 103.138 - slot.put(" ") 103.139 - ui.link{ 103.140 - text = _"(new window)", 103.141 - module = "help", 103.142 - view = "show", 103.143 - id = "wikisyntax", 103.144 - attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 103.145 - } 103.146 - end 103.147 - } 103.148 - end 103.149 - } 103.150 - ui.field.text{ 103.151 - label = _"Statement", 103.152 - name = "statement", 103.153 - multiline = true, 103.154 - attr = { style = "height: 50ex;" }, 103.155 - value = param.get("statement") 103.156 - } 103.157 - 103.158 - 103.159 - ui.submit{ value = _"Save" } 103.160 + slot.put("<br />") 103.161 + ui.container{ attr = { class = "actions" }, content = function() 103.162 + ui.tag{ 103.163 + tag = "input", 103.164 + attr = { 103.165 + type = "submit", 103.166 + class = "btn btn-default", 103.167 + value = _"publish profile data" 103.168 + }, 103.169 + content = "" 103.170 + } 103.171 + slot.put("<br /><br /><br />") 103.172 + ui.link{ 103.173 + content = _"cancel", 103.174 + module = "member", view = "show", id = app.session.member.id 103.175 + } 103.176 + end } 103.177 + end ) 103.178 + end ) 103.179 end 103.180 } 103.181 \ No newline at end of file
104.1 --- a/app/main/member/edit_images.lua Thu Jul 10 01:02:43 2014 +0200 104.2 +++ b/app/main/member/edit_images.lua Thu Jul 10 01:19:48 2014 +0200 104.3 @@ -1,11 +1,15 @@ 104.4 -ui.title(_"Upload images") 104.5 +ui.titleMember(_"avatar/photo") 104.6 104.7 -util.help("member.edit_images", _"Images") 104.8 +execute.view { 104.9 + module = "member", view = "_sidebar_whatcanido", params = { 104.10 + member = app.session.member 104.11 + } 104.12 +} 104.13 104.14 ui.form{ 104.15 record = app.session.member, 104.16 attr = { 104.17 - class = "vertical", 104.18 + class = "vertical section", 104.19 enctype = 'multipart/form-data' 104.20 }, 104.21 module = "member", 104.22 @@ -19,24 +23,52 @@ 104.23 } 104.24 }, 104.25 content = function() 104.26 - execute.view{ 104.27 - module = "member_image", 104.28 - view = "_show", 104.29 - params = { 104.30 - member = app.session.member, 104.31 - image_type = "avatar" 104.32 + ui.sectionHead( function() 104.33 + ui.heading { level = 1, content = _"Upload avatar/photo" } 104.34 + end ) 104.35 + ui.sectionRow( function() 104.36 + execute.view{ 104.37 + module = "member_image", 104.38 + view = "_show", 104.39 + params = { 104.40 + class = "right", 104.41 + member = app.session.member, 104.42 + image_type = "avatar" 104.43 + } 104.44 } 104.45 - } 104.46 - ui.field.image{ field_name = "avatar", label = _"Avatar" } 104.47 - execute.view{ 104.48 - module = "member_image", 104.49 - view = "_show", 104.50 - params = { 104.51 - member = app.session.member, 104.52 - image_type = "photo" 104.53 + ui.heading { level = 2, content = _"Avatar"} 104.54 + ui.container { content = _"Your avatar is a small photo, which will be shown always next to your name." } 104.55 + slot.put("<br />") 104.56 + ui.field.image{ field_name = "avatar" } 104.57 + slot.put("<br /><br />") 104.58 + execute.view{ 104.59 + module = "member_image", 104.60 + view = "_show", 104.61 + params = { 104.62 + class = "right", 104.63 + member = app.session.member, 104.64 + image_type = "photo" 104.65 + } 104.66 } 104.67 - } 104.68 - ui.field.image{ field_name = "photo", label = _"Photo" } 104.69 - ui.submit{ value = _"Save" } 104.70 + ui.heading { level = 2, content = _"Photo"} 104.71 + ui.container { content = _"Your photo will be shown in your profile." } 104.72 + slot.put("<br />") 104.73 + ui.field.image{ field_name = "photo" } 104.74 + slot.put("<br style='clear: right;' />") 104.75 + ui.tag{ 104.76 + tag = "input", 104.77 + attr = { 104.78 + type = "submit", 104.79 + class = "btn btn-default", 104.80 + value = _"publish avatar/photo" 104.81 + }, 104.82 + content = "" 104.83 + } 104.84 + slot.put("<br /><br /><br />") 104.85 + ui.link{ 104.86 + content = _"cancel", 104.87 + module = "member", view = "show", id = app.session.member.id 104.88 + } 104.89 + end ) 104.90 end 104.91 } 104.92 \ No newline at end of file
105.1 --- a/app/main/member/history.lua Thu Jul 10 01:02:43 2014 +0200 105.2 +++ b/app/main/member/history.lua Thu Jul 10 01:19:48 2014 +0200 105.3 @@ -1,76 +1,72 @@ 105.4 local member = Member:by_id(param.get_id()) 105.5 105.6 -slot.select("head", function() 105.7 - ui.container{ 105.8 - attr = { class = "title" }, 105.9 - content = _("Member name history for '#{name}'", { name = member.name }) 105.10 - } 105.11 - ui.container{ attr = { class = "actions" }, content = function() 105.12 - ui.link{ 105.13 +ui.titleMember(member) 105.14 + 105.15 +ui.section( function() 105.16 + 105.17 + ui.sectionHead( function() 105.18 + ui.heading{ level = 1, content = _"Account history" } 105.19 + end) 105.20 + 105.21 + ui.sectionRow( function() 105.22 + ui.form{ 105.23 + attr = { class = "vertical" }, 105.24 content = function() 105.25 - ui.image{ static = "icons/16/cancel.png" } 105.26 - slot.put(_"Back") 105.27 - end, 105.28 - module = "member", 105.29 - view = "show", 105.30 - id = member.id 105.31 + ui.field.text{ label = _"Current name", value = member.name } 105.32 + ui.field.text{ label = _"Current status", value = member.active and _'activated' or _'deactivated' } 105.33 + end 105.34 } 105.35 - end } 105.36 -end) 105.37 - 105.38 -ui.form{ 105.39 - attr = { class = "vertical" }, 105.40 - content = function() 105.41 - ui.field.text{ label = _"Current name", value = member.name } 105.42 - ui.field.text{ label = _"Current status", value = member.active and _'activated' or _'deactivated' } 105.43 - end 105.44 -} 105.45 105.46 105.47 -local entries = member:get_reference_selector("history_entries"):add_order_by("id DESC"):exec() 105.48 - 105.49 -ui.tag{ 105.50 - tag = "table", 105.51 - content = function() 105.52 - ui.tag{ 105.53 - tag = "tr", 105.54 - content = function() 105.55 - ui.tag{ 105.56 - tag = "th", 105.57 - content = _("Name") 105.58 - } 105.59 - ui.tag{ 105.60 - tag = "th", 105.61 - content = _("Status") 105.62 - } 105.63 - ui.tag{ 105.64 - tag = "th", 105.65 - content = _("until") 105.66 - } 105.67 - end 105.68 - } 105.69 - for i, entry in ipairs(entries) do 105.70 + local entries = member:get_reference_selector("history_entries"):add_order_by("id DESC"):exec() 105.71 + 105.72 + if #entries > 0 then 105.73 ui.tag{ 105.74 - tag = "tr", 105.75 + tag = "table", 105.76 content = function() 105.77 ui.tag{ 105.78 - tag = "td", 105.79 - content = entry.name 105.80 + tag = "tr", 105.81 + content = function() 105.82 + ui.tag{ 105.83 + tag = "th", 105.84 + content = _("Name") 105.85 + } 105.86 + ui.tag{ 105.87 + tag = "th", 105.88 + content = _("Status") 105.89 + } 105.90 + ui.tag{ 105.91 + tag = "th", 105.92 + content = _("until") 105.93 + } 105.94 + end 105.95 } 105.96 - ui.tag{ 105.97 - tag = "td", 105.98 - content = entry.active and _'activated' or _'deactivated', 105.99 - } 105.100 - ui.tag{ 105.101 - tag = "td", 105.102 - content = format.timestamp(entry["until"]) 105.103 - } 105.104 + for i, entry in ipairs(entries) do 105.105 + ui.tag{ 105.106 + tag = "tr", 105.107 + content = function() 105.108 + ui.tag{ 105.109 + tag = "td", 105.110 + content = entry.name 105.111 + } 105.112 + ui.tag{ 105.113 + tag = "td", 105.114 + content = entry.active and _'activated' or _'deactivated', 105.115 + } 105.116 + ui.tag{ 105.117 + tag = "td", 105.118 + content = format.timestamp(entry["until"]) 105.119 + } 105.120 + end 105.121 + } 105.122 + end 105.123 end 105.124 } 105.125 end 105.126 - end 105.127 -} 105.128 -slot.put("<br />") 105.129 -ui.container{ 105.130 - content = _("This member account has been created at #{created}", { created = format.timestamp(member.activated)}) 105.131 -} 105.132 + slot.put("<br />") 105.133 + ui.container{ 105.134 + content = _("This member account has been created at #{created}", { created = format.timestamp(member.activated)}) 105.135 + } 105.136 + end) 105.137 + 105.138 +end) 105.139 \ No newline at end of file
106.1 --- a/app/main/member/list.lua Thu Jul 10 01:02:43 2014 +0200 106.2 +++ b/app/main/member/list.lua Thu Jul 10 01:19:48 2014 +0200 106.3 @@ -1,12 +1,19 @@ 106.4 -slot.put_into("title", _"Member list") 106.5 - 106.6 -util.help("member.list") 106.7 +ui.title(_"Member list") 106.8 106.9 local members_selector = Member:new_selector() 106.10 :add_where("activated NOTNULL") 106.11 106.12 -execute.view{ 106.13 - module = "member", 106.14 - view = "_list", 106.15 - params = { members_selector = members_selector } 106.16 -} 106.17 +ui.section( function() 106.18 + 106.19 + ui.sectionHead( function() 106.20 + ui.heading { level = 1, content = _"Member list" } 106.21 + end ) 106.22 + 106.23 + ui.sectionRow( function() 106.24 + execute.view{ 106.25 + module = "member", 106.26 + view = "_list", 106.27 + params = { members_selector = members_selector } 106.28 + } 106.29 + end ) 106.30 +end )
107.1 --- a/app/main/member/settings.lua Thu Jul 10 01:02:43 2014 +0200 107.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 107.3 @@ -1,38 +0,0 @@ 107.4 -ui.title(_"Settings") 107.5 - 107.6 -local pages = {} 107.7 - 107.8 -if not config.locked_profile_fields.name then 107.9 - pages[#pages+1] = { view = "settings_name", text = _"Change your screen name" } 107.10 -end 107.11 -if not config.locked_profile_fields.login then 107.12 - pages[#pages+1] = { view = "settings_login", text = _"Change your login" } 107.13 -end 107.14 -pages[#pages+1] = { view = "settings_password", text = _"Change your password" } 107.15 -if not config.locked_profile_fields.notify_email then 107.16 - pages[#pages+1] = { view = "settings_email", text = _"Change your notification email address" } 107.17 -end 107.18 -pages[#pages+1] = { view = "settings_notification", text = _"Notification settings" } 107.19 -pages[#pages+1] = { view = "developer_settings", text = _"Developer settings" } 107.20 - 107.21 -if config.download_dir then 107.22 - pages[#pages+1] = { module = "index", view = "download", text = _"Database download" } 107.23 -end 107.24 - 107.25 -ui.list{ 107.26 - attr = { class = "menu_list" }, 107.27 - style = "ulli", 107.28 - records = pages, 107.29 - columns = { 107.30 - { 107.31 - content = function(page) 107.32 - ui.link{ 107.33 - module = page.module or "member", 107.34 - view = page.view, 107.35 - text = page.text 107.36 - } 107.37 - end 107.38 - } 107.39 - } 107.40 -} 107.41 -
108.1 --- a/app/main/member/settings_email.lua Thu Jul 10 01:02:43 2014 +0200 108.2 +++ b/app/main/member/settings_email.lua Thu Jul 10 01:19:48 2014 +0200 108.3 @@ -1,6 +1,10 @@ 108.4 -ui.title(_"Change your notification email address") 108.5 +ui.titleMember(_"Email address") 108.6 108.7 -util.help("member.settings.email_address", _"Change email") 108.8 +execute.view { 108.9 + module = "member", view = "_sidebar_whatcanido", params = { 108.10 + member = app.session.member 108.11 + } 108.12 +} 108.13 108.14 ui.form{ 108.15 attr = { class = "vertical" }, 108.16 @@ -9,19 +13,47 @@ 108.17 routing = { 108.18 ok = { 108.19 mode = "redirect", 108.20 - module = "index", 108.21 - view = "index" 108.22 + module = "member", 108.23 + view = "show", 108.24 + id = app.session.member_id 108.25 } 108.26 }, 108.27 content = function() 108.28 - if app.session.member.notify_email then 108.29 - ui.field.text{ label = _"Confirmed address", value = app.session.member.notify_email, readonly = true } 108.30 - end 108.31 - if app.session.member.notify_email_unconfirmed then 108.32 - ui.field.text{ label = _"Unconfirmed address", value = app.session.member.notify_email_unconfirmed, readonly = true } 108.33 - end 108.34 - ui.field.text{ label = _"New address", name = "email" } 108.35 - ui.submit{ value = _"Change email" } 108.36 + ui.section( function() 108.37 + 108.38 + ui.sectionHead( function() 108.39 + ui.heading { level = 1, content = _"Email address for notifications" } 108.40 + end ) 108.41 + 108.42 + ui.sectionRow( function() 108.43 + if app.session.member.notify_email then 108.44 + ui.field.text{ label = _"confirmed address", value = app.session.member.notify_email, readonly = true } 108.45 + end 108.46 + if app.session.member.notify_email_unconfirmed then 108.47 + ui.field.text{ label = _"unconfirmed address", value = app.session.member.notify_email_unconfirmed, readonly = true } 108.48 + end 108.49 + if app.session.member.notify_email or app.session.member.notify_email_unconfirmed then 108.50 + slot.put("<br />") 108.51 + end 108.52 + ui.heading { level = 2, content = _"Enter a new email address:" } 108.53 + ui.field.text{ name = "email" } 108.54 + slot.put("<br />") 108.55 + ui.tag{ 108.56 + tag = "input", 108.57 + attr = { 108.58 + type = "submit", 108.59 + class = "btn btn-default", 108.60 + value = _"Save" 108.61 + }, 108.62 + content = "" 108.63 + } 108.64 + slot.put("<br /><br /><br />") 108.65 + ui.link{ 108.66 + content = _"Cancel", 108.67 + module = "member", view = "show", id = app.session.member.id 108.68 + } 108.69 + end ) 108.70 + end ) 108.71 end 108.72 } 108.73
109.1 --- a/app/main/member/settings_login.lua Thu Jul 10 01:02:43 2014 +0200 109.2 +++ b/app/main/member/settings_login.lua Thu Jul 10 01:19:48 2014 +0200 109.3 @@ -1,21 +1,52 @@ 109.4 -ui.title(_"Change your login") 109.5 +ui.titleMember(_"login name") 109.6 109.7 -util.help("member.settings.login", _"Change login") 109.8 +execute.view { 109.9 + module = "member", view = "_sidebar_whatcanido", params = { 109.10 + member = app.session.member 109.11 + } 109.12 +} 109.13 109.14 ui.form{ 109.15 - attr = { class = "vertical" }, 109.16 + attr = { class = "wide" }, 109.17 module = "member", 109.18 action = "update_login", 109.19 routing = { 109.20 ok = { 109.21 mode = "redirect", 109.22 - module = "index", 109.23 - view = "index" 109.24 + module = "member", 109.25 + view = "show", 109.26 + id = app.session.member_id 109.27 } 109.28 }, 109.29 content = function() 109.30 - ui.field.text{ label = _"Login", name = "login", value = app.session.member.login } 109.31 - ui.submit{ value = _"Change login" } 109.32 + ui.section( function() 109.33 + ui.sectionHead( function() 109.34 + ui.heading { level = 1, content = _"Login name" } 109.35 + end ) 109.36 + 109.37 + ui.sectionRow( function() 109.38 + ui.heading { level = 2, content = _"Enter a new login name" } 109.39 + ui.field.text{ name = "login", value = app.session.member.login } 109.40 + 109.41 + slot.put("<br />") 109.42 + 109.43 + ui.tag{ 109.44 + tag = "input", 109.45 + attr = { 109.46 + type = "submit", 109.47 + class = "btn btn-default", 109.48 + value = _"Save" 109.49 + }, 109.50 + content = "" 109.51 + } 109.52 + slot.put("<br /><br /><br />") 109.53 + 109.54 + ui.link { 109.55 + module = "member", view = "show", id = app.session.member_id, 109.56 + content = _"Cancel" 109.57 + } 109.58 + end ) 109.59 + end ) 109.60 end 109.61 } 109.62
110.1 --- a/app/main/member/settings_name.lua Thu Jul 10 01:02:43 2014 +0200 110.2 +++ b/app/main/member/settings_name.lua Thu Jul 10 01:19:48 2014 +0200 110.3 @@ -1,20 +1,50 @@ 110.4 -ui.title(_"Change your screen name") 110.5 +ui.titleMember(_"Screen name") 110.6 110.7 -util.help("member.settings.name", _"Change name") 110.8 +execute.view { 110.9 + module = "member", view = "_sidebar_whatcanido", params = { 110.10 + member = app.session.member 110.11 + } 110.12 +} 110.13 110.14 ui.form{ 110.15 - attr = { class = "vertical" }, 110.16 + attr = { class = "wide" }, 110.17 module = "member", 110.18 action = "update_name", 110.19 routing = { 110.20 ok = { 110.21 mode = "redirect", 110.22 - module = "index", 110.23 - view = "index" 110.24 + module = "member", 110.25 + view = "show", 110.26 + id = app.session.member_id 110.27 } 110.28 }, 110.29 content = function() 110.30 - ui.field.text{ label = _"Name", name = "name", value = app.session.member.name } 110.31 - ui.submit{ value = _"Change name" } 110.32 + ui.section( function() 110.33 + ui.sectionHead( function() 110.34 + ui.heading { level = 1, content = _"Screen name" } 110.35 + end ) 110.36 + 110.37 + ui.sectionRow( function() 110.38 + ui.heading { level = 2, content = _"Enter a new screen name:" } 110.39 + ui.field.text{ name = "name", value = app.session.member.name } 110.40 + 110.41 + slot.put("<br />") 110.42 + 110.43 + ui.tag{ 110.44 + tag = "input", 110.45 + attr = { 110.46 + type = "submit", 110.47 + class = "btn btn-default", 110.48 + value = _"Save" 110.49 + }, 110.50 + content = "" 110.51 + } 110.52 + slot.put("<br /><br /><br />") 110.53 + ui.link { 110.54 + module = "member", view = "show", id = app.session.member_id, 110.55 + content = _"Cancel" 110.56 + } 110.57 + end ) 110.58 + end ) 110.59 end 110.60 }
111.1 --- a/app/main/member/settings_notification.lua Thu Jul 10 01:02:43 2014 +0200 111.2 +++ b/app/main/member/settings_notification.lua Thu Jul 10 01:19:48 2014 +0200 111.3 @@ -1,6 +1,12 @@ 111.4 -ui.title(_"Notification settings") 111.5 +local return_to = param.get("return_to") 111.6 + 111.7 +ui.titleMember("notification settings") 111.8 111.9 -util.help("member.settings.notification", _"Notification settings") 111.10 +execute.view { 111.11 + module = "member", view = "_sidebar_whatcanido", params = { 111.12 + member = app.session.member 111.13 + } 111.14 +} 111.15 111.16 ui.form{ 111.17 attr = { class = "vertical" }, 111.18 @@ -9,99 +15,138 @@ 111.19 routing = { 111.20 ok = { 111.21 mode = "redirect", 111.22 - module = "index", 111.23 - view = "index" 111.24 + module = return_to == "home" and "index" or "member", 111.25 + view = return_to == "home" and "index" or "show", 111.26 + id = return_to ~= "home" and app.session.member_id or nil 111.27 } 111.28 }, 111.29 content = function() 111.30 - ui.tag{ tag = "p", content = _"I like to receive notifications by email about events in my areas and issues:" } 111.31 - 111.32 - ui.container{ content = function() 111.33 - ui.tag{ 111.34 - tag = "input", 111.35 - attr = { 111.36 - id = "notify_level_none", 111.37 - type = "radio", name = "notify_level", value = "none", 111.38 - checked = app.session.member.notify_level == 'none' and "checked" or nil 111.39 - } 111.40 - } 111.41 - ui.tag{ 111.42 - tag = "label", attr = { ['for'] = "notify_level_none" }, 111.43 - content = _"No notifications at all" 111.44 - } 111.45 - end } 111.46 - 111.47 - slot.put("<br />") 111.48 - 111.49 - ui.container{ content = function() 111.50 - ui.tag{ 111.51 - tag = "input", 111.52 - attr = { 111.53 - id = "notify_level_all", 111.54 - type = "radio", name = "notify_level", value = "all", 111.55 - checked = app.session.member.notify_level == 'all' and "checked" or nil 111.56 - } 111.57 - } 111.58 - ui.tag{ 111.59 - tag = "label", attr = { ['for'] = "notify_level_all" }, 111.60 - content = _"All of them" 111.61 - } 111.62 - end } 111.63 + 111.64 + ui.section( function() 111.65 + 111.66 + ui.sectionHead( function() 111.67 + ui.heading { level = 1, content = _"For which issue phases do you like to receive notification emails?" } 111.68 + end ) 111.69 + 111.70 111.71 - slot.put("<br />") 111.72 + ui.sectionRow( function() 111.73 + 111.74 + ui.container{ content = function() 111.75 + ui.tag{ 111.76 + tag = "input", 111.77 + attr = { 111.78 + id = "notify_level_all", 111.79 + type = "radio", name = "notify_level", value = "all", 111.80 + checked = app.session.member.notify_level == 'all' and "checked" or nil 111.81 + } 111.82 + } 111.83 + ui.tag{ 111.84 + tag = "label", attr = { ['for'] = "notify_level_all" }, 111.85 + content = _"I like to receive notifications" 111.86 + } 111.87 + end } 111.88 + 111.89 + slot.put("<br />") 111.90 + 111.91 + ui.container{ content = function() 111.92 + ui.tag{ 111.93 + tag = "input", 111.94 + attr = { 111.95 + id = "notify_level_discussion", 111.96 + type = "radio", name = "notify_level", value = "discussion", 111.97 + checked = app.session.member.notify_level == 'discussion' and "checked" or nil 111.98 + } 111.99 + } 111.100 + ui.tag{ 111.101 + tag = "label", attr = { ['for'] = "notify_level_discussion" }, 111.102 + content = _"Only for issues reaching the discussion phase" 111.103 + } 111.104 + end } 111.105 + 111.106 + slot.put("<br />") 111.107 111.108 - ui.container{ content = function() 111.109 - ui.tag{ 111.110 - tag = "input", 111.111 - attr = { 111.112 - id = "notify_level_discussion", 111.113 - type = "radio", name = "notify_level", value = "discussion", 111.114 - checked = app.session.member.notify_level == 'discussion' and "checked" or nil 111.115 + ui.container{ content = function() 111.116 + ui.tag{ 111.117 + tag = "input", 111.118 + attr = { 111.119 + id = "notify_level_verification", 111.120 + type = "radio", name = "notify_level", value = "verification", 111.121 + checked = app.session.member.notify_level == 'verification' and "checked" or nil 111.122 + } 111.123 + } 111.124 + ui.tag{ 111.125 + tag = "label", attr = { ['for'] = "notify_level_verification" }, 111.126 + content = _"Only for issues reaching the verification phase" 111.127 + } 111.128 + end } 111.129 + 111.130 + slot.put("<br />") 111.131 + 111.132 + ui.container{ content = function() 111.133 + ui.tag{ 111.134 + tag = "input", 111.135 + attr = { 111.136 + id = "notify_level_voting", 111.137 + type = "radio", name = "notify_level", value = "voting", 111.138 + checked = app.session.member.notify_level == 'voting' and "checked" or nil 111.139 + } 111.140 + } 111.141 + ui.tag{ 111.142 + tag = "label", attr = { ['for'] = "notify_level_voting" }, 111.143 + content = _"Only for issues reaching the voting phase" 111.144 + } 111.145 + end } 111.146 + 111.147 + slot.put("<br />") 111.148 + 111.149 + ui.container{ content = function() 111.150 + ui.tag{ 111.151 + tag = "input", 111.152 + attr = { 111.153 + id = "notify_level_none", 111.154 + type = "radio", name = "notify_level", value = "none", 111.155 + checked = app.session.member.notify_level == 'none' and "checked" or nil 111.156 + } 111.157 + } 111.158 + ui.tag{ 111.159 + tag = "label", attr = { ['for'] = "notify_level_none" }, 111.160 + content = _"I do not like to receive notifications by email" 111.161 + } 111.162 + end } 111.163 + 111.164 + slot.put("<br />") 111.165 + 111.166 + ui.container { content = _"Notifications are only send to you about events in the subject areas you subscribed, the issues you are interested in and the initiatives you are supporting." } 111.167 + 111.168 + 111.169 + slot.put("<br />") 111.170 + 111.171 + ui.tag{ 111.172 + tag = "input", 111.173 + attr = { 111.174 + type = "submit", 111.175 + class = "btn btn-default", 111.176 + value = _"Save" 111.177 + }, 111.178 + content = "" 111.179 } 111.180 - } 111.181 - ui.tag{ 111.182 - tag = "label", attr = { ['for'] = "notify_level_discussion" }, 111.183 - content = _"Only for issues reaching the discussion phase" 111.184 - } 111.185 - end } 111.186 - 111.187 - slot.put("<br />") 111.188 - 111.189 - ui.container{ content = function() 111.190 - ui.tag{ 111.191 - tag = "input", 111.192 - attr = { 111.193 - id = "notify_level_verification", 111.194 - type = "radio", name = "notify_level", value = "verification", 111.195 - checked = app.session.member.notify_level == 'verification' and "checked" or nil 111.196 - } 111.197 - } 111.198 - ui.tag{ 111.199 - tag = "label", attr = { ['for'] = "notify_level_verification" }, 111.200 - content = _"Only for issues reaching the frozen phase" 111.201 - } 111.202 - end } 111.203 + slot.put("<br /><br /><br />") 111.204 + 111.205 + slot.put(" ") 111.206 + if return_to == "home" then 111.207 + ui.link { 111.208 + module = "index", view = "index", 111.209 + content = _"cancel" 111.210 + } 111.211 + else 111.212 + ui.link { 111.213 + module = "member", view = "show", id = app.session.member_id, 111.214 + content = _"cancel" 111.215 + } 111.216 + end 111.217 + end ) 111.218 + end ) 111.219 111.220 - slot.put("<br />") 111.221 - 111.222 - ui.container{ content = function() 111.223 - ui.tag{ 111.224 - tag = "input", 111.225 - attr = { 111.226 - id = "notify_level_voting", 111.227 - type = "radio", name = "notify_level", value = "voting", 111.228 - checked = app.session.member.notify_level == 'voting' and "checked" or nil 111.229 - } 111.230 - } 111.231 - ui.tag{ 111.232 - tag = "label", attr = { ['for'] = "notify_level_voting" }, 111.233 - content = _"Only for issues reaching the voting phase" 111.234 - } 111.235 - end } 111.236 - 111.237 - slot.put("<br />") 111.238 - 111.239 - ui.submit{ value = _"Change notification settings" } 111.240 end 111.241 } 111.242
112.1 --- a/app/main/member/settings_password.lua Thu Jul 10 01:02:43 2014 +0200 112.2 +++ b/app/main/member/settings_password.lua Thu Jul 10 01:19:48 2014 +0200 112.3 @@ -1,22 +1,58 @@ 112.4 -ui.title(_"Change your password") 112.5 +ui.titleMember(_"Password") 112.6 112.7 -util.help("member.settings.password", _"Change password") 112.8 +execute.view { 112.9 + module = "member", view = "_sidebar_whatcanido", params = { 112.10 + member = app.session.member 112.11 + } 112.12 +} 112.13 112.14 ui.form{ 112.15 - attr = { class = "vertical" }, 112.16 + attr = { class = "wide" }, 112.17 module = "member", 112.18 action = "update_password", 112.19 routing = { 112.20 ok = { 112.21 mode = "redirect", 112.22 - module = "index", 112.23 - view = "index" 112.24 + module = "member", 112.25 + view = "show", 112.26 + id = app.session.member_id 112.27 } 112.28 }, 112.29 content = function() 112.30 - ui.field.password{ label = _"Old password", name = "old_password" } 112.31 - ui.field.password{ label = _"New password", name = "new_password1" } 112.32 - ui.field.password{ label = _"Repeat new password", name = "new_password2" } 112.33 - ui.submit{ value = _"Change password" } 112.34 + ui.section( function() 112.35 + ui.sectionHead( function() 112.36 + ui.heading { level = 1, content = _"Password" } 112.37 + end ) 112.38 + 112.39 + ui.sectionRow( function() 112.40 + ui.heading { level = 2, content = _"Enter your current password:" } 112.41 + ui.field.password{ name = "old_password" } 112.42 + 112.43 + slot.put("<br />") 112.44 + 112.45 + ui.heading { level = 2, content = _"Enter a new password:" } 112.46 + ui.field.password{ name = "new_password1" } 112.47 + 112.48 + ui.heading { level = 2, content = _"Enter your new password again please:" } 112.49 + ui.field.password{ name = "new_password2" } 112.50 + 112.51 + slot.put("<br />") 112.52 + 112.53 + ui.tag{ 112.54 + tag = "input", 112.55 + attr = { 112.56 + type = "submit", 112.57 + class = "btn btn-default", 112.58 + value = _"Save" 112.59 + }, 112.60 + content = "" 112.61 + } 112.62 + slot.put("<br /><br /><br />") 112.63 + ui.link { 112.64 + module = "member", view = "show", id = app.session.member_id, 112.65 + content = _"Cancel" 112.66 + } 112.67 + end ) 112.68 + end ) 112.69 end 112.70 } 112.71 \ No newline at end of file
113.1 --- a/app/main/member/show.lua Thu Jul 10 01:02:43 2014 +0200 113.2 +++ b/app/main/member/show.lua Thu Jul 10 01:19:48 2014 +0200 113.3 @@ -1,150 +1,185 @@ 113.4 local member = Member:by_id(param.get_id()) 113.5 113.6 if not member or not member.activated then 113.7 - error("access denied") 113.8 + execute.view { module = "index", view = "404" } 113.9 + request.set_status("404 Not Found") 113.10 + return 113.11 end 113.12 113.13 +local limit = 25 113.14 + 113.15 +local initiated_initiatives = Initiative:new_selector() 113.16 + :join("initiator", nil, { "initiator.initiative_id = initiative.id and initiator.member_id = ?", member.id }) 113.17 + :join("issue", nil, "issue.id = initiative.issue_id") 113.18 + :add_where("issue.closed ISNULL") 113.19 + :add_order_by("initiative.id DESC") 113.20 + :limit(limit+1) 113.21 + :exec() 113.22 + 113.23 +initiated_initiatives:load("issue") 113.24 +initiated_initiatives:load_everything_for_member_id(member.id) 113.25 + 113.26 +local supported_initiatives = Initiative:new_selector() 113.27 + :join("supporter", nil, { "supporter.initiative_id = initiative.id and supporter.member_id = ?", member.id }) 113.28 + :join("issue", nil, "issue.id = initiative.issue_id") 113.29 + :add_where("issue.closed ISNULL") 113.30 + :add_order_by("initiative.id DESC") 113.31 + :limit(limit+1) 113.32 + :exec() 113.33 + 113.34 +supported_initiatives:load("issue") 113.35 +supported_initiatives:load_everything_for_member_id(member.id) 113.36 + 113.37 +local voted_initiatives = Initiative:new_selector() 113.38 + :add_where("initiative.rank = 1") 113.39 + :join("direct_voter", nil, { "direct_voter.issue_id = initiative.issue_id and direct_voter.member_id = ?", member.id }) 113.40 + :join("vote", nil, { "vote.initiative_id = initiative.id and vote.member_id = ?", member.id }) 113.41 + :join("issue", nil, "issue.id = initiative.issue_id") 113.42 + :add_order_by("issue.closed DESC, initiative.id DESC") 113.43 + :add_field("vote.grade", "vote_grade") 113.44 + :add_field("vote.first_preference", "vote_first_preference") 113.45 + :limit(limit+1) 113.46 + :exec() 113.47 + 113.48 +voted_initiatives:load("issue") 113.49 +voted_initiatives:load_everything_for_member_id(member.id) 113.50 + 113.51 +local incoming_delegations_selector = member:get_reference_selector("incoming_delegations") 113.52 + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id AND _member_showtab_issue.closed ISNULL") 113.53 + :add_where("_member_showtab_issue.closed ISNULL") 113.54 + :add_order_by("delegation.unit_id, delegation.area_id, delegation.issue_id") 113.55 + :limit(limit+1) 113.56 + 113.57 +local outgoing_delegations_selector = member:get_reference_selector("outgoing_delegations") 113.58 + :left_join("issue", "_member_showtab_issue", "_member_showtab_issue.id = delegation.issue_id AND _member_showtab_issue.closed ISNULL") 113.59 + :add_where("_member_showtab_issue.closed ISNULL") 113.60 + :add_order_by("delegation.unit_id, delegation.area_id, delegation.issue_id") 113.61 + :limit(limit+1) 113.62 + 113.63 + 113.64 app.html_title.title = member.name 113.65 app.html_title.subtitle = _("Member") 113.66 113.67 -slot.select("head", function() 113.68 - ui.container{ 113.69 - attr = { class = "title" }, 113.70 - content = _("Member '#{member}'", { member = member.name }) 113.71 +ui.titleMember(member) 113.72 + 113.73 +execute.view { 113.74 + module = "member", view = "_sidebar_whatcanido", params = { 113.75 + member = member 113.76 } 113.77 - 113.78 - ui.container{ attr = { class = "actions" }, content = function() 113.79 +} 113.80 113.81 - if member.id == app.session.member_id then 113.82 - ui.link{ 113.83 - content = function() 113.84 - slot.put(encode.html(_"Edit profile")) 113.85 - end, 113.86 - module = "member", 113.87 - view = "edit" 113.88 +execute.view { 113.89 + module = "member", view = "_sidebar_contacts", params = { 113.90 + member = member 113.91 + } 113.92 +} 113.93 + 113.94 + 113.95 +ui.section( function() 113.96 + ui.sectionHead( function() 113.97 + execute.view{ 113.98 + module = "member_image", 113.99 + view = "_show", 113.100 + params = { 113.101 + member = member, 113.102 + image_type = "avatar", 113.103 + show_dummy = true, 113.104 + class = "left" 113.105 } 113.106 - slot.put(" · ") 113.107 - ui.link{ 113.108 - content = function() 113.109 - slot.put(encode.html(_"Upload avatar/photo")) 113.110 - end, 113.111 - module = "member", 113.112 - view = "edit_images" 113.113 - } 113.114 - slot.put(" · ") 113.115 - end 113.116 - ui.link{ 113.117 + } 113.118 + ui.heading{ level = 1, content = member.name } 113.119 + slot.put("<br />") 113.120 + ui.container { 113.121 + attr = { class = "right" }, 113.122 content = function() 113.123 - slot.put(encode.html(_"Show member history")) 113.124 - end, 113.125 - module = "member", 113.126 - view = "history", 113.127 - id = member.id 113.128 + ui.link{ 113.129 + content = _"Account history", 113.130 + module = "member", view = "history", id = member.id 113.131 + } 113.132 + end 113.133 } 113.134 - if not member.active then 113.135 - slot.put(" · ") 113.136 - ui.tag{ 113.137 - attr = { class = "interest deactivated_member_info" }, 113.138 - content = _"This member is inactive" 113.139 - } 113.140 + if member.identification then 113.141 + ui.container{ content = member.identification } 113.142 end 113.143 - if member.locked then 113.144 - slot.put(" · ") 113.145 - ui.tag{ 113.146 - attr = { class = "interest deactivated_member_info" }, 113.147 - content = _"This member is locked" 113.148 + end ) 113.149 + ui.sectionRow( function() 113.150 + execute.view{ 113.151 + module = "member", 113.152 + view = "_profile", 113.153 + params = { member = member } 113.154 + } 113.155 + end ) 113.156 +end ) 113.157 + 113.158 + 113.159 +ui.section( function() 113.160 + ui.sectionHead( function() 113.161 + ui.heading { level = 2, content = _"Initiatives created by this member" } 113.162 + end ) 113.163 + ui.sectionRow( function() 113.164 + for i, initiative in ipairs(initiated_initiatives) do 113.165 + execute.view { 113.166 + module = "initiative", view = "_list", 113.167 + params = { initiative = initiative }, 113.168 + member = member 113.169 } 113.170 end 113.171 - if app.session.member_id and not (member.id == app.session.member.id) then 113.172 - slot.put(" · ") 113.173 - --TODO performance 113.174 - local contact = Contact:by_pk(app.session.member.id, member.id) 113.175 - if contact then 113.176 - ui.link{ 113.177 - text = _"Remove from contacts", 113.178 - module = "contact", 113.179 - action = "remove_member", 113.180 - id = contact.other_member_id, 113.181 - routing = { 113.182 - default = { 113.183 - mode = "redirect", 113.184 - module = request.get_module(), 113.185 - view = request.get_view(), 113.186 - id = param.get_id_cgi(), 113.187 - params = param.get_all_cgi() 113.188 - } 113.189 - } 113.190 - } 113.191 - elseif member.activated then 113.192 - ui.link{ 113.193 - text = _"Add to my contacts", 113.194 - module = "contact", 113.195 - action = "add_member", 113.196 - id = member.id, 113.197 - routing = { 113.198 - default = { 113.199 - mode = "redirect", 113.200 - module = request.get_module(), 113.201 - view = request.get_view(), 113.202 - id = param.get_id_cgi(), 113.203 - params = param.get_all_cgi() 113.204 - } 113.205 - } 113.206 - } 113.207 - end 113.208 + end ) 113.209 +end ) 113.210 + 113.211 +ui.section( function() 113.212 + ui.sectionHead( function() 113.213 + ui.heading { level = 2, content = _"What this member is currently supporting" } 113.214 + end ) 113.215 + ui.sectionRow( function() 113.216 + for i, initiative in ipairs(supported_initiatives) do 113.217 + execute.view { 113.218 + module = "initiative", view = "_list", 113.219 + params = { initiative = initiative }, 113.220 + member = member 113.221 + } 113.222 + end 113.223 + end ) 113.224 +end ) 113.225 + 113.226 +ui.section( function() 113.227 + ui.sectionHead( function() 113.228 + ui.heading { level = 2, content = _"How this member voted" } 113.229 + end ) 113.230 + ui.sectionRow( function() 113.231 + for i, initiative in ipairs(voted_initiatives) do 113.232 + execute.view { 113.233 + module = "initiative", view = "_list", 113.234 + params = { initiative = initiative } 113.235 + } 113.236 end 113.237 - if app.session.member_id then 113.238 - local ignored_member = IgnoredMember:by_pk(app.session.member.id, member.id) 113.239 - slot.put(" · ") 113.240 - if ignored_member then 113.241 - ui.tag{ 113.242 - attr = { class = "interest" }, 113.243 - content = _"You have ignored this member" 113.244 - } 113.245 - slot.put(" · ") 113.246 - ui.link{ 113.247 - text = _"Stop ignoring member", 113.248 - module = "member", 113.249 - action = "update_ignore_member", 113.250 - id = member.id, 113.251 - params = { delete = true }, 113.252 - routing = { 113.253 - default = { 113.254 - mode = "redirect", 113.255 - module = request.get_module(), 113.256 - view = request.get_view(), 113.257 - id = param.get_id_cgi(), 113.258 - params = param.get_all_cgi() 113.259 - } 113.260 - } 113.261 - } 113.262 - elseif member.activated then 113.263 - ui.link{ 113.264 - attr = { class = "interest" }, 113.265 - text = _"Ignore member", 113.266 - module = "member", 113.267 - action = "update_ignore_member", 113.268 - id = member.id, 113.269 - routing = { 113.270 - default = { 113.271 - mode = "redirect", 113.272 - module = request.get_module(), 113.273 - view = request.get_view(), 113.274 - id = param.get_id_cgi(), 113.275 - params = param.get_all_cgi() 113.276 - } 113.277 - } 113.278 - } 113.279 - end 113.280 - end 113.281 - end } 113.282 -end) 113.283 + end ) 113.284 +end ) 113.285 + 113.286 113.287 -util.help("member.show", _"Member page") 113.288 +ui.section( function() 113.289 + ui.sectionHead( function() 113.290 + ui.heading { level = 2, content = _"Outgoing delegations" } 113.291 + end ) 113.292 + ui.sectionRow( function() 113.293 + execute.view { 113.294 + module = "delegation", view = "_list", 113.295 + params = { delegations_selector = outgoing_delegations_selector, outgoing = true }, 113.296 + } 113.297 + end ) 113.298 +end ) 113.299 + 113.300 113.301 -execute.view{ 113.302 - module = "member", 113.303 - view = "_show", 113.304 - params = { member = member } 113.305 -} 113.306 - 113.307 +ui.section( function() 113.308 + 113.309 + ui.sectionHead( function() 113.310 + ui.heading { level = 2, content = _"Incoming delegations" } 113.311 + end ) 113.312 + ui.sectionRow( function() 113.313 + execute.view { 113.314 + module = "delegation", view = "_list", 113.315 + params = { delegations_selector = incoming_delegations_selector, incoming = true }, 113.316 + } 113.317 + end ) 113.318 + 113.319 +end )
114.1 --- a/app/main/membership/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 114.2 +++ b/app/main/membership/_action/update.lua Thu Jul 10 01:19:48 2014 +0200 114.3 @@ -1,26 +1,26 @@ 114.4 local area_id = assert(param.get("area_id", atom.integer), "no area id given") 114.5 local membership = Membership:by_pk(area_id, app.session.member.id) 114.6 114.7 +local area = Area:by_id(area_id) 114.8 if param.get("delete", atom.boolean) then 114.9 if membership then 114.10 membership:destroy() 114.11 - --slot.put_into("notice", _"Membership removed") 114.12 + slot.put_into("notice", _"Subscription removed") 114.13 else 114.14 - --slot.put_into("notice", _"Membership not existent") 114.15 + slot.put_into("notice", _"Subscription already removed") 114.16 end 114.17 return 114.18 end 114.19 114.20 +if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then 114.21 + slot.put_into("error", _"You are not eligible to participate") 114.22 + return false 114.23 +end 114.24 + 114.25 if not membership then 114.26 - local area = Area:by_id(area_id) 114.27 - if not app.session.member:has_voting_right_for_unit_id(area.unit_id) then 114.28 - error("access denied") 114.29 - end 114.30 membership = Membership:new() 114.31 membership.area_id = area_id 114.32 membership.member_id = app.session.member_id 114.33 + membership:save() 114.34 + slot.put_into("notice", _"Subject area subscribed") 114.35 end 114.36 - 114.37 -membership:save() 114.38 - 114.39 ---slot.put_into("notice", _"Membership updated")
115.1 --- a/app/main/opinion/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 115.2 +++ b/app/main/opinion/_action/update.lua Thu Jul 10 01:19:48 2014 +0200 115.3 @@ -6,6 +6,10 @@ 115.4 115.5 local suggestion = Suggestion:by_id(suggestion_id) 115.6 115.7 +local degree = param.get("degree", atom.number) 115.8 +local fulfilled = param.get("fulfilled", atom.boolean) 115.9 + 115.10 + 115.11 if not suggestion then 115.12 slot.put_into("error", _"This suggestion has been meanwhile deleted") 115.13 return false 115.14 @@ -28,7 +32,7 @@ 115.15 return false 115.16 end 115.17 115.18 -if param.get("delete") then 115.19 +if degree == 0 then 115.20 if opinion then 115.21 opinion:destroy() 115.22 end 115.23 @@ -36,9 +40,6 @@ 115.24 return 115.25 end 115.26 115.27 -local degree = param.get("degree", atom.number) 115.28 -local fulfilled = param.get("fulfilled", atom.boolean) 115.29 - 115.30 if degree ~= 0 and not app.session.member:has_voting_right_for_unit_id(suggestion.initiative.issue.area.unit_id) then 115.31 error("access denied") 115.32 end
116.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 116.2 +++ b/app/main/policy/_list.lua Thu Jul 10 01:19:48 2014 +0200 116.3 @@ -0,0 +1,90 @@ 116.4 +local for_area = param.get("for_area", "table") 116.5 + 116.6 +local selector = Policy:new_selector() 116.7 + :add_where("policy.active") 116.8 + :add_order_by("policy.index") 116.9 + 116.10 +if for_area then 116.11 + selector:join("allowed_policy", nil, 116.12 + { "allowed_policy.policy_id = policy.id AND allowed_policy.area_id = ?", for_area.id } 116.13 + ) 116.14 +end 116.15 + 116.16 +local policies = selector:exec() 116.17 + 116.18 + 116.19 +for i, policy in ipairs(policies) do 116.20 + ui.container { 116.21 + attr = { class = "sidebarRow", id = "policy" .. policy.id }, 116.22 + content = function () 116.23 + 116.24 + ui.heading { level = 3, content = policy.name } 116.25 + 116.26 + ui.tag{ 116.27 + content = policy.description 116.28 + } 116.29 + 116.30 + slot.put ( "<br />" ) 116.31 + 116.32 + ui.link { 116.33 + attr = { 116.34 + class = "policy-show-details", 116.35 + onclick = "$('#policy" .. policy.id .. " .policy-details').show(); $('#policy" .. policy.id .. " .policy-show-details').hide(); $('#policy" .. policy.id .. " .policy-hide-details').show(); return false;" 116.36 + }, 116.37 + content = _"show details" 116.38 + } 116.39 + 116.40 + ui.link { 116.41 + attr = { 116.42 + class = "policy-hide-details", 116.43 + onclick = "$('#policy" .. policy.id .. " .policy-details').hide(); $('#policy" .. policy.id .. " .policy-show-details').show(); $('#policy" .. policy.id .. " .policy-hide-details').hide(); return false;", 116.44 + style = "display: none;" 116.45 + }, 116.46 + content = _"hide details" 116.47 + } 116.48 + 116.49 + ui.container { 116.50 + attr = { 116.51 + class = "policy-details", 116.52 + style = "display: none;" 116.53 + }, 116.54 + content = function () 116.55 + 116.56 + ui.heading { level = 4, content = _"Phase durations" } 116.57 + 116.58 + if policy.polling then 116.59 + ui.field.text{ label = _"New" .. ":", value = _"without" } 116.60 + else 116.61 + ui.field.text{ label = _"New" .. ":", value = "≤ " .. policy.admission_time } 116.62 + end 116.63 + ui.field.text{ label = _"Discussion" .. ":", value = policy.discussion_time or _"variable" } 116.64 + ui.field.text{ label = _"Frozen" .. ":", value = policy.verification_time or _"variable" } 116.65 + ui.field.text{ label = _"Voting" .. ":", value = policy.voting_time or _"variable" } 116.66 + 116.67 + ui.heading { level = 4, content = _"Quorums" } 116.68 + 116.69 + if policy.polling then 116.70 + ui.field.text{ label = _"Issue quorum" .. ":", value = _"without" } 116.71 + else 116.72 + ui.field.text{ 116.73 + label = _"Issue quorum" .. ":", 116.74 + value = "≥ " .. tostring(policy.issue_quorum_num) .. "/" .. tostring(policy.issue_quorum_den) 116.75 + } 116.76 + end 116.77 + ui.field.text{ 116.78 + label = _"Initiative quorum" .. ":", 116.79 + value = "≥ " .. tostring(policy.initiative_quorum_num) .. "/" .. tostring(policy.initiative_quorum_den) 116.80 + } 116.81 + ui.field.text{ 116.82 + label = _"Direct majority" .. ":", 116.83 + value = (policy.direct_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.direct_majority_num) .. "/" .. tostring(policy.direct_majority_den) 116.84 + } 116.85 + ui.field.text{ 116.86 + label = _"Indirect majority" .. ":", 116.87 + value = (policy.indirect_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.indirect_majority_num) .. "/" .. tostring(policy.indirect_majority_den) 116.88 + } 116.89 + end 116.90 + } 116.91 + end 116.92 + } 116.93 +end 116.94 \ No newline at end of file
117.1 --- a/app/main/policy/list.lua Thu Jul 10 01:02:43 2014 +0200 117.2 +++ b/app/main/policy/list.lua Thu Jul 10 01:19:48 2014 +0200 117.3 @@ -1,73 +1,3 @@ 117.4 ui.title(_"Policies") 117.5 117.6 -util.help("policy.list", _"Policies") 117.7 -local policies = Policy:new_selector() 117.8 - :add_where("active") 117.9 - :add_order_by("index") 117.10 - :exec() 117.11 - 117.12 -ui.list{ 117.13 - records = policies, 117.14 - columns = { 117.15 - { 117.16 - label_attr = { width = "500" }, 117.17 - label = _"Policy", 117.18 - content = function(policy) 117.19 - ui.link{ 117.20 - module = "policy", view = "show", id = policy.id, 117.21 - attr = { style = "font-weight: bold" }, 117.22 - content = function() 117.23 - slot.put(encode.html(policy.name)) 117.24 - if not policy.active then 117.25 - slot.put(" (", _"disabled", ")") 117.26 - end 117.27 - end 117.28 - } 117.29 - ui.tag{ 117.30 - tag = "div", 117.31 - content = policy.description 117.32 - } 117.33 - end 117.34 - }, 117.35 - { 117.36 - label_attr = { width = "200" }, 117.37 - label = _"Phases", 117.38 - content = function(policy) 117.39 - if policy.polling then 117.40 - ui.field.text{ label = _"New" .. ":", value = _"without" } 117.41 - else 117.42 - ui.field.text{ label = _"New" .. ":", value = "≤ " .. policy.admission_time } 117.43 - end 117.44 - ui.field.text{ label = _"Discussion" .. ":", value = policy.discussion_time or _"variable" } 117.45 - ui.field.text{ label = _"Frozen" .. ":", value = policy.verification_time or _"variable" } 117.46 - ui.field.text{ label = _"Voting" .. ":", value = policy.voting_time or _"variable" } 117.47 - end 117.48 - }, 117.49 - { 117.50 - label_attr = { width = "200" }, 117.51 - label = _"Quorum", 117.52 - content = function(policy) 117.53 - if policy.polling then 117.54 - ui.field.text{ label = _"Issue quorum" .. ":", value = _"without" } 117.55 - else 117.56 - ui.field.text{ 117.57 - label = _"Issue quorum" .. ":", 117.58 - value = "≥ " .. tostring(policy.issue_quorum_num) .. "/" .. tostring(policy.issue_quorum_den) 117.59 - } 117.60 - end 117.61 - ui.field.text{ 117.62 - label = _"Initiative quorum" .. ":", 117.63 - value = "≥ " .. tostring(policy.initiative_quorum_num) .. "/" .. tostring(policy.initiative_quorum_den) 117.64 - } 117.65 - ui.field.text{ 117.66 - label = _"Direct majority" .. ":", 117.67 - value = (policy.direct_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.direct_majority_num) .. "/" .. tostring(policy.direct_majority_den) 117.68 - } 117.69 - ui.field.text{ 117.70 - label = _"Indirect majority" .. ":", 117.71 - value = (policy.indirect_majority_strict and ">" or "≥" ) .. " " .. tostring(policy.indirect_majority_num) .. "/" .. tostring(policy.indirect_majority_den) 117.72 - } 117.73 - end 117.74 - }, 117.75 - } 117.76 -} 117.77 \ No newline at end of file 117.78 +execute.view { module = "policy", view = "_list" } 117.79 \ No newline at end of file
118.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 118.2 +++ b/app/main/slideshow/_index.lua Thu Jul 10 01:19:48 2014 +0200 118.3 @@ -0,0 +1,64 @@ 118.4 +local unit = param.get( "unit", "table" ) 118.5 +local area = param.get( "area", "table" ) 118.6 + 118.7 +local args = { 118.8 + unit_id = unit and unit.id or nil, 118.9 + area_id = area and area.id or nil 118.10 +} 118.11 + 118.12 +local lastWinner = Initiative:getLastWinner( args ) 118.13 +local lastLooser = Initiative:getLastLoser( args ) 118.14 +local nextEndingVoting = Initiative:getNextEndingVoting( args ) 118.15 +local nextEndingVerification = Initiative:getNextEndingVerification( args ) 118.16 +local nextEndingDiscussion = Initiative:getNextEndingDiscussion( args ) 118.17 +local bestInAdmission = Initiative:getBestInAdmission( args ) 118.18 + 118.19 +local slides = { } 118.20 + 118.21 +if lastWinner then 118.22 + slides[#slides+1] = { 118.23 + title = _"Latest approved issue", 118.24 + initiative = lastWinner 118.25 + } 118.26 +end 118.27 + 118.28 +if lastLooser then 118.29 + slides[#slides+1] = { 118.30 + title = _"Latest disapproved issue", 118.31 + initiative = lastLooser 118.32 + } 118.33 +end 118.34 + 118.35 +if nextEndingVoting then 118.36 + slides[#slides+1] = { 118.37 + title = _("Voting #{time_info}", { time_info = nextEndingVoting.issue.state_time_text }), 118.38 + initiative = nextEndingVoting 118.39 + } 118.40 +end 118.41 + 118.42 +if nextEndingVerification then 118.43 + slides[#slides+1] = { 118.44 + title = _("Verification #{time_info}", { time_info = nextEndingVerification.issue.state_time_text }), 118.45 + initiative = nextEndingVerification 118.46 + } 118.47 +end 118.48 + 118.49 +if nextEndingDiscussion then 118.50 + slides[#slides+1] = { 118.51 + title = _("Discussion #{time_info}", { time_info = nextEndingDiscussion.issue.state_time_text }), 118.52 + initiative = nextEndingDiscussion 118.53 + } 118.54 +end 118.55 + 118.56 +if bestInAdmission then 118.57 + slides[#slides+1] = { 118.58 + title = _"Best not admitted initiative", 118.59 + initiative = bestInAdmission 118.60 + } 118.61 +end 118.62 + 118.63 +execute.view { 118.64 + module = "slideshow", view = "_slideshow", params = { 118.65 + slides = slides 118.66 + } 118.67 +}
119.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 119.2 +++ b/app/main/slideshow/_slideshow.lua Thu Jul 10 01:19:48 2014 +0200 119.3 @@ -0,0 +1,79 @@ 119.4 +local slides = param.get( "slides", "table" ) 119.5 + 119.6 +local show_slides = {} 119.7 + 119.8 +for i, slide in ipairs( slides ) do 119.9 + 119.10 + if slide.initiative then 119.11 + show_slides[ #show_slides + 1 ] = slide 119.12 + end 119.13 + 119.14 +end 119.15 + 119.16 +slot.select( "slideshow", function () 119.17 + 119.18 + ui.container { attr = { class = "slideshow" }, content = function () 119.19 + 119.20 + for i, slide in ipairs( show_slides ) do 119.21 + 119.22 + if slide.initiative.issue.closed then 119.23 + view = "finished" 119.24 + elseif slide.initiative.issue.fully_frozen then 119.25 + view = "voting" 119.26 + elseif slide.initiative.issue.half_frozen then 119.27 + view = "verification" 119.28 + elseif slide.initiative.issue.admitted then 119.29 + view = "discussion" 119.30 + else 119.31 + view = "admission" 119.32 + end 119.33 + 119.34 + ui.container { attr = { class = "slide slide-" .. i }, content = function () 119.35 + 119.36 + if slide.initiative.issue.closed then 119.37 + util.initiative_pie(slide.initiative, 150) 119.38 + end 119.39 + 119.40 + ui.container { 119.41 + attr = { class = "slideshowTitle" }, 119.42 + content = slide.title 119.43 + } 119.44 + 119.45 + execute.view { 119.46 + module = "initiative", view = "_list_element", params = { 119.47 + initiative = slide.initiative 119.48 + } 119.49 + } 119.50 + 119.51 + end } 119.52 + 119.53 + end 119.54 + 119.55 + 119.56 + end } 119.57 + 119.58 +end ) 119.59 + 119.60 +ui.script{ script = [[ 119.61 + 119.62 +var slideshowCurrent = 0; 119.63 +var slideshowCount = ]] .. #show_slides .. [[ ; 119.64 +function slideshowShowSlide(i) { 119.65 + $(".slideshow .slide").slideUp(); 119.66 + $(".slideshow .slide-" + i).slideDown(); 119.67 + slideshowCurrent = i; 119.68 +} 119.69 + 119.70 +function slideshowShowNext() { 119.71 + var next = slideshowCurrent + 1; 119.72 + if (next > slideshowCount) { 119.73 + next = 1; 119.74 + } 119.75 + slideshowShowSlide(next); 119.76 + window.setTimeout(slideshowShowNext, 7500); 119.77 +} 119.78 + 119.79 +slideshowShowNext(); 119.80 + 119.81 + 119.82 + ]]} 119.83 \ No newline at end of file
120.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 120.2 +++ b/app/main/slideshow/index.lua Thu Jul 10 01:19:48 2014 +0200 120.3 @@ -0,0 +1,26 @@ 120.4 +local unit = param.get( "unit", "table" ) 120.5 +local area = param.get( "area", "table" ) 120.6 + 120.7 +local args = { 120.8 + unit_id = unit and unit.id or nil, 120.9 + area_id = area and area.id or nil 120.10 +} 120.11 + 120.12 +local issues = Issue:new_selector():exec() 120.13 + 120.14 + 120.15 +local slides = {} 120.16 + 120.17 +for i, issue in ipairs( issues ) do 120.18 + slides[ #slides+1 ] = { 120.19 + title = issue.state_name, 120.20 + initiative = issue.initiatives[1] 120.21 + } 120.22 +end 120.23 + 120.24 + 120.25 +execute.view { 120.26 + module = "slideshow", view = "_slideshow", params = { 120.27 + slides = slides 120.28 + } 120.29 +} 120.30 \ No newline at end of file
121.1 --- a/app/main/suggestion/_action/add.lua Thu Jul 10 01:02:43 2014 +0200 121.2 +++ b/app/main/suggestion/_action/add.lua Thu Jul 10 01:19:48 2014 +0200 121.3 @@ -18,11 +18,11 @@ 121.4 return false 121.5 end 121.6 121.7 -local formatting_engine = param.get("formatting_engine") 121.8 +local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine 121.9 121.10 local formatting_engine_valid = false 121.11 -for fe, dummy in pairs(config.formatting_engine_executeables) do 121.12 - if formatting_engine == fe then 121.13 +for i, fe in ipairs(config.formatting_engines) do 121.14 + if formatting_engine == fe.id then 121.15 formatting_engine_valid = true 121.16 end 121.17 end
122.1 --- a/app/main/suggestion/new.lua Thu Jul 10 01:02:43 2014 +0200 122.2 +++ b/app/main/suggestion/new.lua Thu Jul 10 01:19:48 2014 +0200 122.3 @@ -1,20 +1,5 @@ 122.4 local initiative_id = param.get("initiative_id") 122.5 122.6 -slot.put_into("title", _"Add new suggestion") 122.7 - 122.8 -ui.actions(function() 122.9 - ui.link{ 122.10 - content = function() 122.11 - ui.image{ static = "icons/16/cancel.png" } 122.12 - slot.put(_"Cancel") 122.13 - end, 122.14 - module = "initiative", 122.15 - view = "show", 122.16 - id = initiative_id, 122.17 - params = { tab = "suggestions" } 122.18 - } 122.19 -end) 122.20 - 122.21 ui.form{ 122.22 module = "suggestion", 122.23 action = "add", 122.24 @@ -28,76 +13,94 @@ 122.25 params = { tab = "suggestions" } 122.26 } 122.27 }, 122.28 - attr = { class = "vertical" }, 122.29 + attr = { class = "section vertical" }, 122.30 content = function() 122.31 - local supported = Supporter:by_pk(initiative_id, app.session.member.id) and true or false 122.32 - if not supported then 122.33 - ui.field.text{ 122.34 - attr = { class = "warning" }, 122.35 - value = _"You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter." 122.36 - } 122.37 - end 122.38 - ui.field.select{ 122.39 - label = _"Degree", 122.40 - name = "degree", 122.41 - foreign_records = { 122.42 - { id = 1, name = _"should"}, 122.43 - { id = 2, name = _"must"}, 122.44 - }, 122.45 - foreign_id = "id", 122.46 - foreign_name = "name" 122.47 - } 122.48 - ui.field.text{ label = _"Title (80 chars max)", name = "name" } 122.49 - ui.field.select{ 122.50 - label = _"Wiki engine", 122.51 - name = "formatting_engine", 122.52 - foreign_records = { 122.53 - { id = "rocketwiki", name = "RocketWiki" }, 122.54 - { id = "compat", name = _"Traditional wiki syntax" } 122.55 - }, 122.56 - attr = {id = "formatting_engine"}, 122.57 - foreign_id = "id", 122.58 - foreign_name = "name", 122.59 - value = param.get("formatting_engine") 122.60 - } 122.61 - ui.tag{ 122.62 - tag = "div", 122.63 - content = function() 122.64 - ui.tag{ 122.65 - tag = "label", 122.66 - attr = { class = "ui_field_label" }, 122.67 - content = function() slot.put(" ") end, 122.68 + 122.69 + ui.sectionHead( function() 122.70 + ui.heading { level = 1, content = _"Add a new suggestion for improvement" } 122.71 + end) 122.72 + 122.73 + ui.sectionRow( function() 122.74 + 122.75 + local supported = Supporter:by_pk(initiative_id, app.session.member.id) and true or false 122.76 + if not supported then 122.77 + ui.field.text{ 122.78 + attr = { class = "warning" }, 122.79 + value = _"You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter." 122.80 + } 122.81 + end 122.82 + ui.field.text{ label = _"A short title (80 chars max)", name = "name" } 122.83 + 122.84 + if not config.enforce_formatting_engine then 122.85 + ui.field.select{ 122.86 + label = _"Wiki engine", 122.87 + name = "formatting_engine", 122.88 + foreign_records = config.formatting_engines, 122.89 + attr = {id = "formatting_engine"}, 122.90 + foreign_id = "id", 122.91 + foreign_name = "name", 122.92 + value = param.get("formatting_engine") 122.93 } 122.94 ui.tag{ 122.95 + tag = "div", 122.96 content = function() 122.97 - ui.link{ 122.98 - text = _"Syntax help", 122.99 - module = "help", 122.100 - view = "show", 122.101 - id = "wikisyntax", 122.102 - attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 122.103 + ui.tag{ 122.104 + tag = "label", 122.105 + attr = { class = "ui_field_label" }, 122.106 + content = function() slot.put(" ") end, 122.107 } 122.108 - slot.put(" ") 122.109 - ui.link{ 122.110 - text = _"(new window)", 122.111 - module = "help", 122.112 - view = "show", 122.113 - id = "wikisyntax", 122.114 - attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 122.115 + ui.tag{ 122.116 + content = function() 122.117 + ui.link{ 122.118 + text = _"Syntax help", 122.119 + module = "help", 122.120 + view = "show", 122.121 + id = "wikisyntax", 122.122 + attr = {onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 122.123 + } 122.124 + slot.put(" ") 122.125 + ui.link{ 122.126 + text = _"(new window)", 122.127 + module = "help", 122.128 + view = "show", 122.129 + id = "wikisyntax", 122.130 + attr = {target = "_blank", onClick="this.href=this.href.replace(/wikisyntax[^.]*/g, 'wikisyntax_'+getElementById('formatting_engine').value)"} 122.131 + } 122.132 + end 122.133 } 122.134 end 122.135 } 122.136 end 122.137 - } 122.138 - ui.field.text{ 122.139 - label = _"Description", 122.140 - name = "content", 122.141 - multiline = true, 122.142 - attr = { style = "height: 50ex;" }, 122.143 - value = param.get("content") 122.144 - } 122.145 + 122.146 + ui.field.text{ 122.147 + label = _"Describe how the proposal and/or the reasons of the initiative could be improved", 122.148 + name = "content", 122.149 + multiline = true, 122.150 + attr = { style = "height: 50ex;" }, 122.151 + value = param.get("content") 122.152 + } 122.153 122.154 - 122.155 - ui.submit{ text = _"Commit suggestion" } 122.156 + ui.field.select{ 122.157 + label = _"How important is your suggestions for you?", 122.158 + name = "degree", 122.159 + foreign_records = { 122.160 + { id = 1, name = _"should be implemented"}, 122.161 + { id = 2, name = _"must be implemented"}, 122.162 + }, 122.163 + foreign_id = "id", 122.164 + foreign_name = "name" 122.165 + } 122.166 + 122.167 + ui.submit{ text = _"publish suggestion" } 122.168 + slot.put(" ") 122.169 + ui.link{ 122.170 + content = _"cancel", 122.171 + module = "initiative", 122.172 + view = "show", 122.173 + id = initiative_id, 122.174 + params = { tab = "suggestions" } 122.175 + } 122.176 + 122.177 + end ) 122.178 end 122.179 }
123.1 --- a/app/main/supporter/show_incoming.lua Thu Jul 10 01:02:43 2014 +0200 123.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 123.3 @@ -1,21 +0,0 @@ 123.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) 123.5 -local issue = initiative.issue 123.6 -local member = Member:by_id(param.get("member_id", atom.integer)) 123.7 - 123.8 -local members_selector = Member:new_selector() 123.9 - :join("delegating_interest_snapshot", nil, "delegating_interest_snapshot.member_id = member.id") 123.10 - :join("issue", nil, "issue.id = delegating_interest_snapshot.issue_id") 123.11 - :add_where{ "delegating_interest_snapshot.issue_id = ?", issue.id } 123.12 - :add_where{ "delegating_interest_snapshot.event = ?", issue.latest_snapshot_event } 123.13 - :add_where{ "delegating_interest_snapshot.delegate_member_ids[1] = ?", member.id } 123.14 - :add_field{ "delegating_interest_snapshot.weight" } 123.15 - 123.16 -execute.view{ 123.17 - module = "member", 123.18 - view = "_list", 123.19 - params = { 123.20 - members_selector = members_selector, 123.21 - issue = issue, 123.22 - trustee = member 123.23 - } 123.24 -} 123.25 \ No newline at end of file
124.1 --- a/app/main/timeline/_action/delete_filter.lua Thu Jul 10 01:02:43 2014 +0200 124.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 124.3 @@ -1,3 +0,0 @@ 124.4 -local timeline_filter = app.session.member:get_setting_map_by_key_and_subkey("timeline_filters", param.get("name")) 124.5 - 124.6 -timeline_filter:destroy() 124.7 \ No newline at end of file
125.1 --- a/app/main/timeline/_action/save.lua Thu Jul 10 01:02:43 2014 +0200 125.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 125.3 @@ -1,45 +0,0 @@ 125.4 -local id = param.get("id", atom.number) 125.5 - 125.6 -local setting_key = "liquidfeedback_frontend_timeline_current_options" 125.7 -local setting = Setting:by_pk(app.session.member.id, setting_key) 125.8 -local options_string = setting.value 125.9 - 125.10 -local timeline_filter 125.11 - 125.12 -local subkey = param.get("name") 125.13 - 125.14 -if not subkey or subkey == "" then 125.15 - slot.put_into("error", _"This name is really too short!") 125.16 - request.redirect{ 125.17 - module = "timeline", 125.18 - view = "save_filter", 125.19 - } 125.20 - return 125.21 -end 125.22 - 125.23 -app.session.member:set_setting_map("timeline_filters", subkey, options_string) 125.24 - 125.25 -local timeline_params = {} 125.26 -if options_string then 125.27 - for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do 125.28 - timeline_params["option_" .. event_ident] = true 125.29 - if filter_idents ~= "*" then 125.30 - for filter_ident in filter_idents:gmatch("([^\|]+)") do 125.31 - timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true 125.32 - end 125.33 - end 125.34 - end 125.35 -end 125.36 - 125.37 -local setting_key = "liquidfeedback_frontend_timeline_current_date" 125.38 -local setting = Setting:by_pk(app.session.member.id, setting_key) 125.39 - 125.40 -if setting then 125.41 - timeline_params.date = setting.value 125.42 -end 125.43 - 125.44 -request.redirect{ 125.45 - module = "timeline", 125.46 - view = "index", 125.47 - params = timeline_params 125.48 -} 125.49 \ No newline at end of file
126.1 --- a/app/main/timeline/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 126.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 126.3 @@ -1,112 +0,0 @@ 126.4 -execute.view{ 126.5 - module = "timeline", 126.6 - view = "_constants" 126.7 -} 126.8 - 126.9 -local options_string = param.get("options_string") 126.10 - 126.11 -if not options_string then 126.12 - local active_options = "" 126.13 - for event_ident, event_name in pairs(event_names) do 126.14 - if param.get("option_" .. event_ident, atom.boolean) then 126.15 - active_options = active_options .. event_ident .. ":" 126.16 - local filter_idents = {} 126.17 - for filter_ident, filter_name in pairs(filter_names) do 126.18 - if param.get("option_" .. event_ident .. "_" .. filter_ident, atom.boolean) then 126.19 - filter_idents[#filter_idents+1] = filter_ident 126.20 - end 126.21 - end 126.22 - if #filter_idents > 0 then 126.23 - active_options = active_options .. table.concat(filter_idents, "|") .. " " 126.24 - else 126.25 - active_options = active_options .. "* " 126.26 - end 126.27 - end 126.28 - end 126.29 - if #active_options > 0 then 126.30 - options_string = active_options 126.31 - end 126.32 -end 126.33 - 126.34 -if not options_string then 126.35 - options_string = "issue_created:* issue_finished_after_voting:* issue_accepted:* issue_voting_started:* suggestion_created:* issue_canceled:* initiative_created:* issue_finished_without_voting:* draft_created:* initiative_revoked:* issue_half_frozen:* " 126.36 -end 126.37 - 126.38 -if param.get_list("option_ignore_area", atom.string) then 126.39 - options_string = options_string.." ignore_area:"..table.concat(param.get_list("option_ignore_area", atom.string), "|") 126.40 -end 126.41 - 126.42 -local setting_key = "liquidfeedback_frontend_timeline_current_options" 126.43 -local setting = Setting:by_pk(app.session.member.id, setting_key) 126.44 - 126.45 -if not setting or setting.value ~= options_string then 126.46 - if not setting then 126.47 - setting = Setting:new() 126.48 - setting.member_id = app.session.member_id 126.49 - setting.key = setting_key 126.50 - end 126.51 - if options_string then 126.52 - setting.value = options_string 126.53 - setting:save() 126.54 - end 126.55 -end 126.56 - 126.57 -local date = param.get("date") 126.58 - 126.59 -if param.get("search_from") == "last_24h" then 126.60 - date = "last_24h" 126.61 -end 126.62 - 126.63 -if date and #date > 0 then 126.64 - local setting_key = "liquidfeedback_frontend_timeline_current_date" 126.65 - local setting = Setting:by_pk(app.session.member.id, setting_key) 126.66 - if not setting or setting.value ~= date then 126.67 - if not setting then 126.68 - setting = Setting:new() 126.69 - setting.member_id = app.session.member.id 126.70 - setting.key = setting_key 126.71 - end 126.72 - setting.value = date 126.73 - setting:save() 126.74 - end 126.75 -end 126.76 - 126.77 -local setting_key = "liquidfeedback_frontend_timeline_current_options" 126.78 -local setting = Setting:by_pk(app.session.member.id, setting_key) 126.79 - 126.80 -local timeline_params = {} 126.81 -if setting and setting.value then 126.82 - for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do 126.83 - timeline_params["option_" .. event_ident] = true 126.84 - if filter_idents ~= "*" then 126.85 - for filter_ident in filter_idents:gmatch("([^\|]+)") do 126.86 - timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true 126.87 - end 126.88 - end 126.89 - end 126.90 -end 126.91 - 126.92 -local setting_key = "liquidfeedback_frontend_timeline_current_date" 126.93 -local setting = Setting:by_pk(app.session.member.id, setting_key) 126.94 - 126.95 -if setting then 126.96 - timeline_params.date = setting.value 126.97 -end 126.98 - 126.99 -timeline_params.show_options = param.get("show_options", atom.boolean) 126.100 - 126.101 -if param.get("save", atom.boolean) then 126.102 - request.redirect{ 126.103 - module = "timeline", 126.104 - view = "save_filter", 126.105 - params = { 126.106 - current_name = param.get("current_name") 126.107 - } 126.108 - } 126.109 -else 126.110 - request.redirect{ 126.111 - module = "timeline", 126.112 - view = "index", 126.113 - params = timeline_params 126.114 - } 126.115 -end 126.116 \ No newline at end of file
127.1 --- a/app/main/timeline/_constants.lua Thu Jul 10 01:02:43 2014 +0200 127.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 127.3 @@ -1,31 +0,0 @@ 127.4 -event_names = { 127.5 - issue_created = _"New issue", 127.6 - issue_canceled = _"Issue canceled", 127.7 - issue_accepted = _"Issue accepted", 127.8 - issue_half_frozen = _"Issue frozen", 127.9 - issue_finished_without_voting = _"Issue finished without voting", 127.10 - issue_voting_started = _"Voting started", 127.11 - issue_finished_after_voting = _"Issue finished", 127.12 - initiative_created = _"New initiative", 127.13 - initiative_revoked = _"Initiative revoked", 127.14 - draft_created = _"New draft", 127.15 - suggestion_created = _"New suggestion" 127.16 -} 127.17 - 127.18 -filter_names = { 127.19 - contact = _"Saved as contact", 127.20 - interested = _"Interested", 127.21 - supporter = _"Supported", 127.22 - potential_supporter = _"Potential supported", 127.23 - initiator = _"Initiated", 127.24 - membership = _"Member of area" 127.25 -} 127.26 - 127.27 -option_names = {} 127.28 -for key, val in pairs(event_names) do 127.29 - option_names[key] = val 127.30 -end 127.31 -for key, val in pairs(filter_names) do 127.32 - option_names[key] = val 127.33 -end 127.34 -
128.1 --- a/app/main/timeline/_filter/29_filter.lua Thu Jul 10 01:02:43 2014 +0200 128.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 128.3 @@ -1,42 +0,0 @@ 128.4 -if request.get_view() == "index" and not param.get("date") then 128.5 - local setting 128.6 - local setting_key = "liquidfeedback_frontend_timeline_current_options" 128.7 - if app.session.member_id then 128.8 - setting = Setting:by_pk(app.session.member.id, setting_key) 128.9 - end 128.10 - 128.11 - local timeline_params = {} 128.12 - if setting and setting.value then 128.13 - for event_ident, filter_idents in setting.value:gmatch("(%S+):(%S+)") do 128.14 - timeline_params["option_" .. event_ident] = true 128.15 - if filter_idents ~= "*" then 128.16 - for filter_ident in filter_idents:gmatch("([^\|]+)") do 128.17 - timeline_params["option_" .. event_ident .. "_" .. filter_ident] = true 128.18 - end 128.19 - end 128.20 - end 128.21 - end 128.22 - 128.23 - local setting 128.24 - local setting_key = "liquidfeedback_frontend_timeline_current_date" 128.25 - if app.session.member_id then 128.26 - setting = Setting:by_pk(app.session.member.id, setting_key) 128.27 - end 128.28 - 128.29 - if setting then 128.30 - timeline_params.date = setting.value 128.31 - else 128.32 - timeline_params.date = "last_24h" 128.33 - end 128.34 - 128.35 - timeline_params.show_options = param.get("show_options", atom.boolean) 128.36 - 128.37 - request.redirect{ 128.38 - module = "timeline", 128.39 - view = "index", 128.40 - params = timeline_params 128.41 - } 128.42 -else 128.43 - execute.inner() 128.44 -end 128.45 -
129.1 --- a/app/main/timeline/_list.lua Thu Jul 10 01:02:43 2014 +0200 129.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 129.3 @@ -1,145 +0,0 @@ 129.4 -local timeline_selector = param.get("timeline_selector", "table") 129.5 -local event_names = param.get("event_names", "table") 129.6 -local initiatives_per_page = param.get("initiatives_per_page", atom.number) or 3 129.7 - 129.8 - 129.9 --- test if selector is valid 129.10 -local test_selector = timeline_selector:get_db_conn():new_selector() 129.11 -test_selector:add_field('count(1)') 129.12 -test_selector:add_from(timeline_selector) 129.13 -test_selector:single_object_mode() 129.14 - 129.15 -err, x = test_selector:try_exec() 129.16 - 129.17 -if err then 129.18 - slot.put_into("error", _"Invalid query") 129.19 -else 129.20 - ui.paginate{ 129.21 - per_page = param.get("per_page", atom.number) or 25, 129.22 - selector = timeline_selector, 129.23 - container_attr = { class = "ui_paginate timeline_results" }, 129.24 - content = function() 129.25 - local timelines = timeline_selector:exec() 129.26 - timelines:load("issue") 129.27 - timelines:load("initiative") 129.28 - timelines:load("member") 129.29 - ui.list{ 129.30 - attr = { class = "nohover" }, 129.31 - records = timelines, 129.32 - columns = { 129.33 - { 129.34 - field_attr = { style = "width: 10em;" }, 129.35 - content = function(timeline) 129.36 - ui.field.text{ 129.37 - attr = { style = "font-size: 75%; font-weight: bold; background-color: #ccc; display: block; margin-bottom: 1ex;"}, 129.38 - value = format.time(timeline.occurrence) 129.39 - } 129.40 - 129.41 - ui.field.text{ 129.42 - attr = { style = "font-size: 75%; font-weight: bold;"}, 129.43 - value = event_names[timeline.event] or timeline.event 129.44 - } 129.45 - if timeline.event == "draft_created" and timeline.count > 1 then 129.46 - ui.field.text{ 129.47 - attr = { style = "font-size: 75%;"}, 129.48 - value = _("(#{more_count} duplicates removed)", { more_count = timeline.count - 1 }) 129.49 - } 129.50 - end 129.51 - end 129.52 - }, 129.53 - { 129.54 - content = function(timeline) 129.55 - local issue 129.56 - local initiative 129.57 - if timeline.issue then 129.58 - issue = timeline.issue 129.59 - elseif timeline.initiative then 129.60 - initiative = timeline.initiative 129.61 - issue = initiative.issue 129.62 - elseif timeline.draft then 129.63 - initiative = timeline.draft.initiative 129.64 - issue = initiative.issue 129.65 - elseif timeline.suggestion then 129.66 - initiative = timeline.suggestion.initiative 129.67 - issue = initiative.issue 129.68 - end 129.69 - if issue then 129.70 - if timeline.is_interested then 129.71 - local label = _"You are interested in this issue", 129.72 - ui.image{ 129.73 - attr = { alt = label, title = label, style = "float: left; margin-right: 0.5em;" }, 129.74 - static = "icons/16/eye.png" 129.75 - } 129.76 - end 129.77 - slot.put(" ") 129.78 - ui.tag{ 129.79 - tag = "span", 129.80 - attr = { style = "font-size: 75%; font-weight: bold; background-color: #ccc; display: block; margin-bottom: 1ex;"}, 129.81 - content = issue.area.name_with_unit_name .. ", " .. _("Issue ##{id}", { id = issue.id }) 129.82 - } 129.83 - else 129.84 - ui.tag{ 129.85 - tag = "span", 129.86 - attr = { style = "font-size: 75%; background-color: #ccc; display: block; margin-bottom: 1ex;"}, 129.87 - content = function() slot.put(" ") end 129.88 - } 129.89 - end 129.90 - 129.91 - if timeline.member then 129.92 - execute.view{ 129.93 - module = "member_image", 129.94 - view = "_show", 129.95 - params = { 129.96 - member = timeline.member, 129.97 - image_type = "avatar", 129.98 - show_dummy = true 129.99 - } 129.100 - } 129.101 - ui.link{ 129.102 - content = timeline.member.name, 129.103 - module = "member", 129.104 - view = "show", 129.105 - id = timeline.member.id 129.106 - } 129.107 - end 129.108 - if timeline.issue then 129.109 - local initiatives_selector = timeline.issue 129.110 - :get_reference_selector("initiatives") 129.111 - execute.view{ 129.112 - module = "initiative", 129.113 - view = "_list", 129.114 - params = { 129.115 - issue = timeline.issue, 129.116 - initiatives_selector = initiatives_selector, 129.117 - per_page = initiatives_per_page, 129.118 - no_sort = true, 129.119 - limit = initiatives_per_page 129.120 - } 129.121 - } 129.122 - elseif initiative then 129.123 - execute.view{ 129.124 - module = "initiative", 129.125 - view = "_list", 129.126 - params = { 129.127 - issue = initiative.issue, 129.128 - initiatives_selector = Initiative:new_selector():add_where{ "initiative.id = ?", initiative.id }, 129.129 - per_page = initiatives_per_page, 129.130 - no_sort = true 129.131 - } 129.132 - } 129.133 - end 129.134 - if timeline.suggestion then 129.135 - ui.link{ 129.136 - module = "suggestion", 129.137 - view = "show", 129.138 - id = timeline.suggestion.id, 129.139 - content = timeline.suggestion.name 129.140 - } 129.141 - end 129.142 - end 129.143 - }, 129.144 - } 129.145 - } 129.146 - end 129.147 - } 129.148 -end
130.1 --- a/app/main/timeline/index.lua Thu Jul 10 01:02:43 2014 +0200 130.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 130.3 @@ -1,449 +0,0 @@ 130.4 -execute.view{ 130.5 - module = "timeline", 130.6 - view = "_constants" 130.7 -} 130.8 - 130.9 -local active_name = "" 130.10 -local areas_ignored = {} 130.11 -local options_box_count = param.get("options_box_count", atom.number) or 1 130.12 -if options_box_count > 10 then 130.13 - options_box_count = 10 130.14 -end 130.15 - 130.16 -local function format_dow(dow) 130.17 - local dows = { 130.18 - _"Monday", 130.19 - _"Tuesday", 130.20 - _"Wednesday", 130.21 - _"Thursday", 130.22 - _"Friday", 130.23 - _"Saturday", 130.24 - _"Sunday" 130.25 - } 130.26 - return dows[dow+1] 130.27 -end 130.28 -slot.put_into("title", _"Timeline") 130.29 - 130.30 -slot.select("actions", function() 130.31 - local setting_key = "liquidfeedback_frontend_timeline_current_options" 130.32 - local setting = Setting:by_pk(app.session.member.id, setting_key) 130.33 - local current_options = "" 130.34 - if setting then 130.35 - current_options = setting.value 130.36 - end 130.37 - local setting_maps = app.session.member:get_setting_maps_by_key("timeline_filters") 130.38 - for i, setting_map in ipairs(setting_maps) do 130.39 - local active 130.40 - local options_string = setting_map.value 130.41 - local name = setting_map.subkey 130.42 - if options_string == current_options then 130.43 - active = true 130.44 - active_name = name 130.45 - end 130.46 - ui.link{ 130.47 - image = { static = "icons/16/time.png" }, 130.48 - attr = { class = active and "action_active" or nil }, 130.49 - text = name, 130.50 - form_attr = { class = "inline" }, 130.51 - module = 'timeline', 130.52 - action = 'update', 130.53 - params = { 130.54 - options_string = options_string 130.55 - }, 130.56 - } 130.57 - end 130.58 - if #setting_maps > 0 then 130.59 - ui.link{ 130.60 - content = function() 130.61 - ui.image{ static = "icons/16/wrench.png" } 130.62 - slot.put(_"Manage filter") 130.63 - end, 130.64 - module = "timeline", 130.65 - view = "list_filter", 130.66 - } 130.67 - end 130.68 - ui.link{ 130.69 - content = function() 130.70 - ui.image{ static = "icons/16/bullet_disk.png" } 130.71 - slot.put(_"Save current filter") 130.72 - end, 130.73 - module = "timeline", 130.74 - view = "save_filter", 130.75 - params = { 130.76 - current_name = active_name 130.77 - }, 130.78 - attr = { 130.79 - onclick = "el=document.getElementById('timeline_save');el.checked=true;el.form.submit();return(false);" 130.80 - } 130.81 - } 130.82 -end) 130.83 - 130.84 -util.help("timeline.index", _"Timeline") 130.85 - 130.86 -ui.form{ 130.87 - module = "timeline", 130.88 - action = "update", 130.89 - content = function() 130.90 - ui.container{ 130.91 - 130.92 - content = function() 130.93 - 130.94 - ui.tag{ 130.95 - tag = "input", 130.96 - attr = { 130.97 - type = "radio", 130.98 - id = "timeline_search_last_24h", 130.99 - name = "search_from", 130.100 - value = "last_24h", 130.101 - checked = param.get("date") == "last_24h" and "checked" or nil 130.102 - }, 130.103 - } 130.104 - 130.105 - ui.tag{ 130.106 - tag = "label", 130.107 - attr = { 130.108 - ["for"] = "timeline_search_last_24h" 130.109 - }, 130.110 - content = " " .. _"last 24 hours" .. " " 130.111 - } 130.112 - 130.113 - ui.tag{ 130.114 - tag = "input", 130.115 - attr = { 130.116 - type = "radio", 130.117 - id = "timeline_search_from_date", 130.118 - name = "search_from", 130.119 - value = "date", 130.120 - checked = not (param.get("date") == "last_24h") and "checked" or nil 130.121 - }, 130.122 - } 130.123 - 130.124 - slot.put(" ") 130.125 - local current_date = param.get("date") 130.126 - if not current_date or #current_date == 0 or current_date == "last_24h" then 130.127 - current_date = tostring(db:query("select now()::date as date")[1].date) 130.128 - end 130.129 - ui.tag{ 130.130 - tag = "input", 130.131 - attr = { 130.132 - type = "text", 130.133 - id = "timeline_search_date", 130.134 - style = "width: 10em;", 130.135 - onchange = "this.form.submit();", 130.136 - onclick = "document.getElementById('timeline_search_from_date').checked = true;", 130.137 - name = "date", 130.138 - value = current_date 130.139 - }, 130.140 - content = function() end 130.141 - } 130.142 - 130.143 - ui.script{ static = "gregor.js/gregor.js" } 130.144 - util.gregor("timeline_search_date", true) 130.145 - 130.146 - 130.147 - ui.link{ 130.148 - attr = { style = "margin-left: 1em; font-weight: bold;", onclick = "document.getElementById('timeline_search_date').form.submit();return(false);" }, 130.149 - content = function() 130.150 - ui.image{ 130.151 - attr = { style = "margin-right: 0.25em;" }, 130.152 - static = "icons/16/magnifier.png" 130.153 - } 130.154 - slot.put(_"Search") 130.155 - end, 130.156 - external = "#", 130.157 - } 130.158 - local show_options = param.get("show_options", atom.boolean) 130.159 - ui.link{ 130.160 - attr = { style = "margin-left: 1em;", onclick = "el=document.getElementById('timeline_show_options');el.checked=" .. tostring(not show_options) .. ";el.form.submit();return(false);" }, 130.161 - content = function() 130.162 - ui.image{ 130.163 - attr = { style = "margin-right: 0.25em;" }, 130.164 - static = "icons/16/text_list_bullets.png" 130.165 - } 130.166 - slot.put(not show_options and _"Show filter details" or _"Hide filter details") 130.167 - end, 130.168 - external = "#", 130.169 - } 130.170 - 130.171 - ui.field.boolean{ 130.172 - attr = { id = "timeline_show_options", style = "display: none;", onchange="this.form.submit();" }, 130.173 - name = "show_options", 130.174 - value = param.get("show_options", atom.boolean) 130.175 - } 130.176 - ui.hidden_field{ name = "current_name", value = active_name } 130.177 - ui.field.boolean{ 130.178 - attr = { id = "timeline_save", style = "display: none;", onchange="this.form.submit();" }, 130.179 - name = "save", 130.180 - value = false 130.181 - } 130.182 - 130.183 - end 130.184 - } 130.185 - 130.186 - ui.container{ 130.187 - attr = { 130.188 - id = "timeline_options_boxes", 130.189 - class = "vertical", 130.190 - style = not param.get("show_options", atom.boolean) and "display: none;" or nil 130.191 - }, 130.192 - content = function() 130.193 - 130.194 - local function option_field(event_ident, filter_ident) 130.195 - local param_name 130.196 - if not filter_ident then 130.197 - param_name = "option_" .. event_ident 130.198 - else 130.199 - param_name = "option_" .. event_ident .. "_" .. filter_ident 130.200 - end 130.201 - local value = param.get(param_name, atom.boolean) 130.202 - ui.field.boolean{ 130.203 - attr = { id = param_name }, 130.204 - name = param_name, 130.205 - value = value, 130.206 - } 130.207 - end 130.208 - 130.209 - local function filter_option_fields(event_ident, filter_idents) 130.210 - 130.211 - for i, filter_ident in ipairs(filter_idents) do 130.212 - slot.put("<td>") 130.213 - option_field(event_ident, filter_ident) 130.214 - slot.put("</td><td><div class='ui_field_label label_right'>") 130.215 - ui.tag{ 130.216 - attr = { ["for"] = "option_" .. event_ident .. "_" .. filter_ident }, 130.217 - tag = "label", 130.218 - content = filter_names[filter_ident] 130.219 - } 130.220 - slot.put("</div></td>") 130.221 - end 130.222 - 130.223 - end 130.224 - 130.225 - local event_groups = { 130.226 - { 130.227 - title = _"Issue events", 130.228 - event_idents = { 130.229 - "issue_created", 130.230 - "issue_canceled", 130.231 - "issue_accepted", 130.232 - "issue_half_frozen", 130.233 - "issue_finished_without_voting", 130.234 - "issue_voting_started", 130.235 - "issue_finished_after_voting", 130.236 - }, 130.237 - filter_idents = { 130.238 - "membership", 130.239 - "interested" 130.240 - } 130.241 - }, 130.242 - { 130.243 - title = _"Initiative events", 130.244 - event_idents = { 130.245 - "initiative_created", 130.246 - "initiative_revoked", 130.247 - "draft_created", 130.248 - "suggestion_created", 130.249 - }, 130.250 - filter_idents = { 130.251 - "membership", 130.252 - "interested", 130.253 - "supporter", 130.254 - "potential_supporter", 130.255 - "initiator" 130.256 - } 130.257 - } 130.258 - } 130.259 - 130.260 - slot.put("<table>") 130.261 - 130.262 - for i_event_group, event_group in ipairs(event_groups) do 130.263 - slot.put("<tr>") 130.264 - slot.put("<th colspan='2'>") 130.265 - slot.put(event_group.title) 130.266 - slot.put("</th><th colspan='10'>") 130.267 - slot.put(_"Show only events which match... (or associtated)") 130.268 - slot.put("</th>") 130.269 - slot.put("</tr>") 130.270 - local event_idents = event_group.event_idents 130.271 - for i, event_ident in ipairs(event_idents) do 130.272 - slot.put("<tr><td>") 130.273 - option_field(event_ident) 130.274 - slot.put("</td><td><div class='ui_field_label label_right'>") 130.275 - ui.tag{ 130.276 - attr = { ["for"] = "option_" .. event_ident }, 130.277 - tag = "label", 130.278 - content = event_names[event_ident] 130.279 - } 130.280 - slot.put("</div></td>") 130.281 - filter_option_fields(event_ident, event_group.filter_idents) 130.282 - slot.put("</tr>") 130.283 - end 130.284 - end 130.285 - 130.286 - slot.put("</table>") 130.287 - 130.288 - local areas = Area:new_selector():add_where("active='t'"):exec() 130.289 - for i, area in ipairs(areas) do 130.290 - if param.get("option_ignore_area_"..tostring(area.id)) then 130.291 - areas_ignored[#areas_ignored+1] = area.id 130.292 - end 130.293 - end 130.294 - 130.295 - ui.multiselect{ 130.296 - style = "checkbox", 130.297 - selected_ids = areas_ignored, 130.298 - container_attr = { class = "ignore_area_list" }, 130.299 - container2_attr = { class = "ignore_area_item" }, 130.300 - label = _"Ignore Areas", 130.301 - name = "option_ignore_area[]", 130.302 - foreign_records = areas, 130.303 - foreign_id = "id", 130.304 - foreign_name = "name" 130.305 - } 130.306 - 130.307 - end 130.308 - } 130.309 - end 130.310 -} 130.311 - 130.312 -local date = param.get("date") 130.313 - 130.314 -if not date or #date == 0 then 130.315 - date = "today" 130.316 -end 130.317 - 130.318 -local timeline_selector 130.319 - 130.320 -for event, event_name in pairs(event_names) do 130.321 - 130.322 - if param.get("option_" .. event, atom.boolean) then 130.323 - 130.324 - local tmp = Timeline:new_selector() 130.325 - if event == "draft_created" then 130.326 - tmp 130.327 - :reset_fields() 130.328 - :add_field("max(timeline.occurrence)", "occurrence") 130.329 - :add_field("timeline.event", nil, { "grouped" }) 130.330 - :add_field("timeline.issue_id", nil, { "grouped" }) 130.331 - :add_field("draft.initiative_id", nil, { "grouped" }) 130.332 - :add_field("max(timeline.draft_id)", "draft_id") 130.333 - :add_field("timeline.suggestion_id", nil, { "grouped" }) 130.334 - :add_field("COUNT(*)", "count") 130.335 - else 130.336 - tmp 130.337 - :add_field("1", "count") 130.338 - end 130.339 - 130.340 - if date == "last_24h" then 130.341 - tmp:add_where{ "occurrence > now() - '24 hours'::interval" } 130.342 - else 130.343 - local start,stop = string.gmatch(date, "(%d+-%d+-%d+):(%d+-%d+-%d+)")() 130.344 - if start and stop then 130.345 - tmp:add_where{ "occurrence::date >= ?::date AND occurrence::date <= ?::date", start, stop } 130.346 - else 130.347 - local age = string.gmatch(date, "age:(.+)")() 130.348 - if age then 130.349 - tmp:add_where{ "occurrence >= now() - ?::interval", age } 130.350 - else 130.351 - local since = string.gmatch(date, "since:%s*(%d+-%d+-%d+)%s*")() 130.352 - if since then 130.353 - tmp:add_where{ "occurrence::date >= ?::date", since } 130.354 - else 130.355 - tmp:add_where{ "occurrence::date = ?::date", date } 130.356 - end 130.357 - end 130.358 - end 130.359 - end 130.360 - tmp 130.361 - :left_join("draft", nil, "draft.id = timeline.draft_id") 130.362 - :left_join("suggestion", nil, "suggestion.id = timeline.suggestion_id") 130.363 - :left_join("initiative", nil, "initiative.id = timeline.initiative_id or initiative.id = draft.initiative_id or initiative.id = suggestion.initiative_id") 130.364 - :left_join("issue", nil, "issue.id = timeline.issue_id or issue.id = initiative.issue_id") 130.365 - :left_join("area", nil, "area.id = issue.area_id") 130.366 - 130.367 - :left_join("interest", "_interest", { "_interest.issue_id = issue.id AND _interest.member_id = ?", app.session.member.id} ) 130.368 - :left_join("initiator", "_initiator", { "_initiator.initiative_id = initiative.id AND _initiator.member_id = ?", app.session.member.id} ) 130.369 - :left_join("membership", "_membership", { "_membership.area_id = area.id AND _membership.member_id = ?", app.session.member.id} ) 130.370 - :left_join("supporter", "_supporter", { "_supporter.initiative_id = initiative.id AND _supporter.member_id = ?", app.session.member.id} ) 130.371 - 130.372 - local group 130.373 - if event == "draft_created" then 130.374 - group = { "grouped" } 130.375 - tmp:add_where{"EXISTS(SELECT 1 from draft as cdraft WHERE draft.initiative_id = cdraft.initiative_id AND cdraft.id != draft.id ORDER BY cdraft.id DESC)"} 130.376 - end 130.377 - 130.378 - tmp 130.379 - :add_field("(_interest.member_id NOTNULL)", "is_interested", group) 130.380 - :add_field("(_initiator.member_id NOTNULL)", "is_initiator", group) 130.381 - :add_field({"(_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_supporter", group) 130.382 - :add_field({"EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1)", app.session.member.id }, "is_potential_supporter", group) 130.383 - -- :left_join("member", nil, "member.id = timeline.member_id", group) 130.384 - 130.385 - if #areas_ignored > 0 then 130.386 - tmp:add_where{"area.id NOT IN ($)", areas_ignored} 130.387 - end 130.388 - 130.389 - tmp:add_where{ "event = ?", event } 130.390 - 130.391 - local filters = {} 130.392 - if param.get("option_" .. event .. "_membership", atom.boolean) then 130.393 - filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _membership.member_id NOTNULL" 130.394 - end 130.395 - 130.396 - if param.get("option_" .. event .. "_supporter", atom.boolean) then 130.397 - filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND NOT EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))" 130.398 - end 130.399 - 130.400 - if param.get("option_" .. event .. "_potential_supporter", atom.boolean) then 130.401 - filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR ((_supporter.member_id NOTNULL) AND EXISTS(SELECT NULL FROM opinion WHERE opinion.initiative_id = initiative.id AND opinion.member_id = ? AND ((opinion.degree = 2 AND NOT fulfilled) OR (opinion.degree = -2 AND fulfilled)) LIMIT 1))" 130.402 - end 130.403 - 130.404 - if param.get("option_" .. event .. "_interested", atom.boolean) then 130.405 - filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _interest.member_id NOTNULL" 130.406 - end 130.407 - 130.408 - if param.get("option_" .. event .. "_initiator", atom.boolean) then 130.409 - filters[#filters+1] = "(timeline.initiative_id ISNULL AND timeline.issue_id ISNULL AND timeline.draft_id ISNULL AND timeline.suggestion_id ISNULL) OR _initiator.member_id NOTNULL" 130.410 - end 130.411 - 130.412 - if #filters > 0 then 130.413 - local filter_string = "(" .. table.concat(filters, ") OR (") .. ")" 130.414 - tmp:add_where{ filter_string, app.session.member.id, app.session.member.id } 130.415 - end 130.416 - 130.417 - if not timeline_selector then 130.418 - timeline_selector = tmp 130.419 - else 130.420 - timeline_selector:union_all(tmp) 130.421 - end 130.422 - end 130.423 -end 130.424 - 130.425 -if timeline_selector then 130.426 - 130.427 - local initiatives_per_page = param.get("initiatives_per_page", atom.number) 130.428 - 130.429 - local outer_timeline_selector = db:new_selector() 130.430 - outer_timeline_selector._class = Timeline 130.431 - outer_timeline_selector 130.432 - :add_field{ "timeline.*" } 130.433 - :from({"($)", { timeline_selector }}, "timeline" ) 130.434 - :add_order_by("occurrence DESC") 130.435 - 130.436 - slot.put("<br />") 130.437 - execute.view{ 130.438 - module = "timeline", 130.439 - view = "_list", 130.440 - params = { 130.441 - timeline_selector = outer_timeline_selector, 130.442 - per_page = param.get("per_page", atom.number), 130.443 - event_names = event_names, 130.444 - initiatives_per_page = initiatives_per_page 130.445 - } 130.446 - } 130.447 - 130.448 -else 130.449 - 130.450 - slot.put(_"No events selected to list") 130.451 - 130.452 -end 130.453 \ No newline at end of file
131.1 --- a/app/main/timeline/list_filter.lua Thu Jul 10 01:02:43 2014 +0200 131.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 131.3 @@ -1,34 +0,0 @@ 131.4 -slot.put_into("title", _"Manage timeline filters") 131.5 - 131.6 -slot.select("actions", function() 131.7 - ui.link{ 131.8 - image = { static = "icons/16/cancel.png" }, 131.9 - text = _"Back to timeline", 131.10 - module = "timeline", 131.11 - action = "update" 131.12 - } 131.13 -end) 131.14 - 131.15 -local timeline_filters = app.session.member:get_setting_maps_by_key("timeline_filters") 131.16 - 131.17 -ui.list{ 131.18 - records = timeline_filters, 131.19 - columns = { 131.20 - { 131.21 - name = "subkey" 131.22 - }, 131.23 - { 131.24 - content = function(timeline_filter) 131.25 - ui.link{ 131.26 - attr = { class = "action" }, 131.27 - text = _"Delete filter", 131.28 - module = "timeline", 131.29 - action = "delete_filter", 131.30 - params = { 131.31 - name = timeline_filter.subkey 131.32 - } 131.33 - } 131.34 - end 131.35 - } 131.36 - } 131.37 -} 131.38 \ No newline at end of file
132.1 --- a/app/main/timeline/save_filter.lua Thu Jul 10 01:02:43 2014 +0200 132.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 132.3 @@ -1,28 +0,0 @@ 132.4 -slot.put_into("title", _"Save timeline filters") 132.5 - 132.6 -slot.select("actions", function() 132.7 - ui.link{ 132.8 - content = function() 132.9 - ui.image{ static = "icons/16/cancel.png" } 132.10 - slot.put(_"Cancel") 132.11 - end, 132.12 - module = "timeline", 132.13 - view = "index" 132.14 - } 132.15 -end) 132.16 - 132.17 -ui.form{ 132.18 - attr = { class = "vertical" }, 132.19 - module = "timeline", 132.20 - action = "save", 132.21 - content = function() 132.22 - ui.field.text{ 132.23 - label = _"Name", 132.24 - name = "name", 132.25 - value = param.get("current_name") 132.26 - } 132.27 - ui.submit{ 132.28 - text = _"Save" 132.29 - } 132.30 - end 132.31 -}
133.1 --- a/app/main/unit/_head.lua Thu Jul 10 01:02:43 2014 +0200 133.2 +++ b/app/main/unit/_head.lua Thu Jul 10 01:19:48 2014 +0200 133.3 @@ -1,49 +1,32 @@ 133.4 local unit = param.get("unit", "table") 133.5 -local member = param.get("member", "table") 133.6 - 133.7 -local show_content = param.get("show_content", atom.boolean) 133.8 133.9 -if app.session.member_id then 133.10 - unit:load_delegation_info_once_for_member_id(app.session.member_id) 133.11 -end 133.12 - 133.13 -ui.container{ attr = { class = "unit_head" }, content = function() 133.14 +ui.title ( function () 133.15 133.16 - execute.view{ module = "delegation", view = "_info", params = { unit = unit, member = member } } 133.17 + ui.tag{ attr = { class = "unit" }, content = function() 133.18 + -- unit link 133.19 + ui.link { 133.20 + attr = { class = "unit" }, 133.21 + content = function() 133.22 + ui.tag{ attr = { class = "name" }, content = unit.name } 133.23 + end, 133.24 + module = "unit", view = "show", 133.25 + id = unit.id 133.26 + } 133.27 133.28 - ui.container{ attr = { class = "title" }, content = function() 133.29 - if not config.single_unit_id then 133.30 - ui.link{ 133.31 - module = "unit", view = "show", id = unit.id, 133.32 - attr = { class = "unit_name" }, content = unit.name 133.33 + execute.view { 133.34 + module = "delegation", view = "_info", params = { 133.35 + unit = unit, member = member 133.36 } 133.37 - else 133.38 - ui.link{ 133.39 - module = "unit", view = "show", id = unit.id, 133.40 - attr = { class = "unit_name" }, content = _"LiquidFeedback" .. " · " .. config.instance_name 133.41 + } 133.42 + 133.43 + if config.single_unit_id and not app.session.member_id and config.motd_public then 133.44 + ui.container{ 133.45 + attr = { class = "wiki motd" }, 133.46 + content = function() 133.47 + slot.put(config.motd_public) 133.48 + end 133.49 } 133.50 end 133.51 end } 133.52 - 133.53 - if show_content then 133.54 - ui.container{ attr = { class = "content" }, content = function() 133.55 - 133.56 - if member and member:has_voting_right_for_unit_id(unit.id) then 133.57 - if app.session.member_id == member.id then 133.58 - ui.tag{ content = _"You have voting privileges for this unit" } 133.59 - slot.put(" · ") 133.60 - if unit.delegation_info.first_trustee_id == nil then 133.61 - ui.link{ text = _"Delegate unit", module = "delegation", view = "show", params = { unit_id = unit.id } } 133.62 - else 133.63 - ui.link{ text = _"Change unit delegation", module = "delegation", view = "show", params = { unit_id = unit.id } } 133.64 - end 133.65 - else 133.66 - ui.tag{ content = _"Member has voting privileges for this unit" } 133.67 - end 133.68 - end 133.69 - end } 133.70 - else 133.71 - slot.put("<br />") 133.72 - end 133.73 - 133.74 -end } 133.75 + 133.76 +end ) 133.77 \ No newline at end of file
134.1 --- a/app/main/unit/_list.lua Thu Jul 10 01:02:43 2014 +0200 134.2 +++ b/app/main/unit/_list.lua Thu Jul 10 01:19:48 2014 +0200 134.3 @@ -1,3 +1,4 @@ 134.4 +local for_admin = param.get("for_admin", atom.boolean) 134.5 local units = Unit:get_flattened_tree{ active = true } 134.6 134.7 ui.container{ attr = { class = "box" }, content = function() 134.8 @@ -11,7 +12,11 @@ 134.9 for i = 1, unit.depth - 1 do 134.10 slot.put(" ") 134.11 end 134.12 - ui.link{ text = unit.name, module = "unit", view = "show", id = unit.id } 134.13 + if for_admin then 134.14 + ui.link{ text = unit.name, module = "admin", view = "unit_edit", id = unit.id } 134.15 + else 134.16 + ui.link{ text = unit.name, module = "unit", view = "show", id = unit.id } 134.17 + end 134.18 end 134.19 } 134.20 }
135.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 135.2 +++ b/app/main/unit/_sidebar.lua Thu Jul 10 01:19:48 2014 +0200 135.3 @@ -0,0 +1,80 @@ 135.4 +local member = param.get ( "member", "table" ) or app.session.member 135.5 + 135.6 +local unit = param.get ( "unit", "table" ) 135.7 + 135.8 +local areas_selector = Area:new_selector() 135.9 + :reset_fields() 135.10 + :add_field("area.id", nil, { "grouped" }) 135.11 + :add_field("area.unit_id", nil, { "grouped" }) 135.12 + :add_field("area.name", nil, { "grouped" }) 135.13 + :add_where{ "area.unit_id = ?", unit.id } 135.14 + :add_where{ "area.active" } 135.15 + :add_order_by("area.name") 135.16 + 135.17 +if member then 135.18 + areas_selector:left_join ( 135.19 + "membership", nil, 135.20 + { "membership.area_id = area.id AND membership.member_id = ?", member.id } 135.21 + ) 135.22 + areas_selector:add_field("membership.member_id NOTNULL", "subscribed", { "grouped" }) 135.23 +end 135.24 + 135.25 + 135.26 +local areas = areas_selector:exec() 135.27 +if member then 135.28 + unit:load_delegation_info_once_for_member_id(member.id) 135.29 + areas:load_delegation_info_once_for_member_id(member.id) 135.30 +end 135.31 + 135.32 + 135.33 +ui.sidebar ( "tab-whatcanido", function () 135.34 + 135.35 + ui.sidebarHead( function () 135.36 + ui.heading { 135.37 + level = 2, content = _"Subject areas" 135.38 + } 135.39 + end ) 135.40 + 135.41 + if #areas > 0 then 135.42 + 135.43 + ui.container { class = "areas", content = function () 135.44 + 135.45 + for i, area in ipairs ( areas ) do 135.46 + 135.47 + ui.container { attr = { class = "sidebarRow" }, content = function () 135.48 + 135.49 + if member then 135.50 + local delegation = Delegation:by_pk(member.id, nil, area.id, nil) 135.51 + 135.52 + if delegation then 135.53 + ui.link { 135.54 + module = "delegation", view = "show", params = { 135.55 + area_id = area.id 135.56 + }, 135.57 + attr = { class = "delegation_info" }, 135.58 + content = function () 135.59 + ui.delegation(delegation.trustee_id, delegation.trustee_id and delegation.trustee.name) 135.60 + end 135.61 + } 135.62 + end 135.63 + end 135.64 + 135.65 + if area.subscribed then 135.66 + ui.image { attr = { class = "icon24 star" }, static = "icons/48/star.png" } 135.67 + end 135.68 + 135.69 + ui.link { 135.70 + attr = { class = "area" }, 135.71 + module = "area", view = "show", id = area.id, 135.72 + content = area.name 135.73 + } 135.74 + 135.75 + end } -- ui.tag "li" 135.76 + 135.77 + end -- for i, area 135.78 + 135.79 + end } -- ui.tag "ul" 135.80 + 135.81 + end -- if #areas > 0 135.82 + 135.83 +end ) -- ui.sidebar 135.84 \ No newline at end of file
136.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 136.2 +++ b/app/main/unit/_sidebar_members.lua Thu Jul 10 01:19:48 2014 +0200 136.3 @@ -0,0 +1,33 @@ 136.4 +if not app.session:has_access("all_pseudonymous") then 136.5 + return 136.6 +end 136.7 + 136.8 +local unit = param.get("unit", "table") 136.9 +local members_selector = Member:new_selector() 136.10 + :join("privilege", nil, { "privilege.member_id = member.id AND privilege.unit_id = ? AND privilege.voting_right", unit.id }) 136.11 + :add_where("active") 136.12 + :limit(50) 136.13 + 136.14 +local member_count = unit.member_count or 0 136.15 + 136.16 +ui.sidebar ( "tab-members", function () 136.17 + ui.sidebarHead( function () 136.18 + ui.heading { 136.19 + level = 2, 136.20 + content = _("Eligible members (#{count})", { count = member_count }) 136.21 + } 136.22 + end ) 136.23 + execute.view { 136.24 + module = 'member', view = '_list', params = { 136.25 + members_selector = members_selector, 136.26 + no_filter = true, no_paginate = true, 136.27 + member_class = "sidebarRow sidebarRowNarrow" 136.28 + } 136.29 + } 136.30 + if member_count > members_selector:count() then 136.31 + ui.link { 136.32 + text = _"Show all members", 136.33 + module = "member", view = "list" 136.34 + } 136.35 + end 136.36 +end )
137.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 137.2 +++ b/app/main/unit/_sidebar_whatcanido.lua Thu Jul 10 01:19:48 2014 +0200 137.3 @@ -0,0 +1,69 @@ 137.4 +local unit = param.get ( "unit", "table" ) 137.5 + 137.6 +ui.sidebar ( "tab-whatcanido", function () 137.7 + 137.8 + ui.sidebarHeadWhatCanIDo() 137.9 + 137.10 + if app.session.member then 137.11 + 137.12 + if app.session.member:has_voting_right_for_unit_id ( unit.id ) then 137.13 + ui.sidebarSection( function () 137.14 + 137.15 + if not unit.delegation_info.first_trustee_id then 137.16 + ui.heading{ level = 3, content = _"I want to delegate this organizational unit" } 137.17 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 137.18 + ui.tag { tag = "li", content = function () 137.19 + ui.link { 137.20 + module = "delegation", view = "show", params = { 137.21 + unit_id = unit.id, 137.22 + }, 137.23 + content = _("choose delegatee", { 137.24 + unit_name = unit.name 137.25 + }) 137.26 + } 137.27 + end } 137.28 + end } 137.29 + else 137.30 + ui.container { attr = { class = "right" }, content = function() 137.31 + local member = Member:by_id(unit.delegation_info.first_trustee_id) 137.32 + execute.view{ 137.33 + module = "member_image", 137.34 + view = "_show", 137.35 + params = { 137.36 + member = member, 137.37 + image_type = "avatar", 137.38 + show_dummy = true 137.39 + } 137.40 + } 137.41 + end } 137.42 + ui.heading{ level = 3, content = _"You delegated this unit" } 137.43 + 137.44 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 137.45 + ui.tag { tag = "li", content = function () 137.46 + ui.link { 137.47 + module = "delegation", view = "show", params = { 137.48 + unit_id = unit.id, 137.49 + }, 137.50 + content = _("change/revoke delegation", { 137.51 + unit_name = unit.name 137.52 + }) 137.53 + } 137.54 + end } 137.55 + end } 137.56 + end 137.57 + end ) 137.58 + 137.59 + ui.sidebarSection( function() 137.60 + ui.heading { level = 3, content = _"I want to start a new initiative" } 137.61 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 137.62 + ui.tag { tag = "li", content = _"Open the appropriate subject area where your issue fits in and follow the instruction on that page." } 137.63 + end } 137.64 + end ) 137.65 + 137.66 + else 137.67 + ui.sidebarSection( _"You are not entitled to vote in this unit" ) 137.68 + end 137.69 + 137.70 + end 137.71 + 137.72 +end ) 137.73 \ No newline at end of file
138.1 --- a/app/main/unit/list.lua Thu Jul 10 01:02:43 2014 +0200 138.2 +++ b/app/main/unit/list.lua Thu Jul 10 01:19:48 2014 +0200 138.3 @@ -1,10 +1,10 @@ 138.4 -slot.put_into("title", _"Unit list") 138.5 - 138.6 -util.help("unit.list", _"Unit list") 138.7 +ui.title(_"Unit list") 138.8 138.9 -slot.put("<br />") 138.10 +ui.section( function() 138.11 + ui.sectionRow( function() 138.12 + execute.view{ module = "unit", view = "_list" } 138.13 + end) 138.14 +end ) 138.15 138.16 -execute.view{ module = "unit", view = "_list" } 138.17 138.18 -slot.put("<br />") 138.19
139.1 --- a/app/main/unit/show.lua Thu Jul 10 01:02:43 2014 +0200 139.2 +++ b/app/main/unit/show.lua Thu Jul 10 01:19:48 2014 +0200 139.3 @@ -2,19 +2,14 @@ 139.4 139.5 local unit = Unit:by_id(unit_id) 139.6 139.7 -slot.select("head", function() 139.8 - execute.view{ module = "unit", view = "_head", params = { unit = unit, show_content = true, member = app.session.member } } 139.9 -end) 139.10 +if not unit then 139.11 + execute.view { module = "index", view = "404" } 139.12 + request.set_status("404 Not Found") 139.13 + return 139.14 +end 139.15 139.16 -if config.single_unit_id and not app.session.member_id and config.motd_public then 139.17 - local help_text = config.motd_public 139.18 - ui.container{ 139.19 - attr = { class = "wiki motd" }, 139.20 - content = function() 139.21 - slot.put(format.wiki_text(help_text)) 139.22 - end 139.23 - } 139.24 -end 139.25 + 139.26 +unit:load_delegation_info_once_for_member_id(app.session.member_id) 139.27 139.28 local areas_selector = Area:build_selector{ active = true, unit_id = unit_id } 139.29 areas_selector:add_order_by("member_weight DESC") 139.30 @@ -43,49 +38,38 @@ 139.31 :add_where("issue.closed NOTNULL") 139.32 :add_order_by("issue.closed DESC") 139.33 139.34 -local tabs = { 139.35 - module = "unit", 139.36 - view = "show", 139.37 - id = unit.id 139.38 -} 139.39 + 139.40 139.41 -tabs[#tabs+1] = { 139.42 - name = "areas", 139.43 - label = _"Areas", 139.44 - module = "area", 139.45 - view = "_list", 139.46 - params = { areas_selector = areas_selector, member = app.session.member } 139.47 -} 139.48 +execute.view { module = "unit", view = "_head", params = { unit = unit } } 139.49 139.50 -tabs[#tabs+1] = { 139.51 - name = "timeline", 139.52 - label = _"Latest events", 139.53 - module = "event", 139.54 - view = "_list", 139.55 - params = { for_unit = unit } 139.56 -} 139.57 139.58 -tabs[#tabs+1] = { 139.59 - name = "open", 139.60 - label = _"Open issues", 139.61 - module = "issue", 139.62 - view = "_list", 139.63 - params = { 139.64 - for_state = "open", 139.65 - issues_selector = open_issues_selector, for_unit = true 139.66 - } 139.67 -} 139.68 -tabs[#tabs+1] = { 139.69 - name = "closed", 139.70 - label = _"Closed issues", 139.71 - module = "issue", 139.72 - view = "_list", 139.73 - params = { 139.74 - for_state = "closed", 139.75 - issues_selector = closed_issues_selector, for_unit = true 139.76 +execute.view { 139.77 + module = "unit", view = "_sidebar", params = { 139.78 + unit = unit 139.79 } 139.80 } 139.81 139.82 +execute.view { 139.83 + module = "unit", view = "_sidebar_whatcanido", params = { 139.84 + unit = unit 139.85 + } 139.86 +} 139.87 + 139.88 +execute.view { 139.89 + module = "unit", view = "_sidebar_members", params = { 139.90 + unit = unit 139.91 + } 139.92 +} 139.93 + 139.94 +execute.view { 139.95 + module = "issue", 139.96 + view = "_list2", 139.97 + params = { for_unit = unit, head = function () 139.98 + ui.heading { attr = { class = "left" }, level = 1, content = unit.name } 139.99 + end } 139.100 +} 139.101 + 139.102 +--[[ 139.103 if app.session:has_access("all_pseudonymous") then 139.104 tabs[#tabs+1] = { 139.105 name = "eligible_voters", 139.106 @@ -104,4 +88,6 @@ 139.107 } 139.108 end 139.109 139.110 -ui.tabs(tabs) 139.111 \ No newline at end of file 139.112 +ui.tabs(tabs) 139.113 + 139.114 +--]] 139.115 \ No newline at end of file
140.1 --- a/app/main/vote/_action/update.lua Thu Jul 10 01:02:43 2014 +0200 140.2 +++ b/app/main/vote/_action/update.lua Thu Jul 10 01:19:48 2014 +0200 140.3 @@ -3,19 +3,23 @@ 140.4 140.5 local issue = Issue:new_selector():add_where{ "id = ?", param.get("issue_id", atom.integer) }:for_share():single_object_mode():exec() 140.6 140.7 -local preview = param.get("preview") and true or false 140.8 +local preview = (param.get("preview") or param.get("edit")) and true or false 140.9 140.10 if not app.session.member:has_voting_right_for_unit_id(issue.area.unit_id) then 140.11 error("access denied") 140.12 end 140.13 140.14 -local update_comment = param.get("update_comment") == "1" and true or false 140.15 +local update_comment = param.get("update_comment") and true or false 140.16 140.17 if issue.state ~= "voting" and not issue.closed then 140.18 slot.put_into("error", _"Voting has not started yet.") 140.19 return false 140.20 end 140.21 140.22 +if (issue.phase_finished or issue.closed) and preview then 140.23 + return 140.24 +end 140.25 + 140.26 if issue.phase_finished or issue.closed and not update_comment then 140.27 slot.put_into("error", _"This issue is already closed.") 140.28 return false 140.29 @@ -66,7 +70,22 @@ 140.30 end 140.31 end 140.32 140.33 - local formatting_engine = param.get("formatting_engine") 140.34 + local formatting_engine 140.35 + if config.enforce_formatting_engine then 140.36 + formatting_engine = config.enforce_formatting_engine 140.37 + else 140.38 + formatting_engine = param.get("formatting_engine") 140.39 + local formatting_engine_valid = false 140.40 + for i, fe in ipairs(config.formatting_engines) do 140.41 + if formatting_engine == fe.id then 140.42 + formatting_engine_valid = true 140.43 + end 140.44 + end 140.45 + if not formatting_engine_valid then 140.46 + error("invalid formatting engine!") 140.47 + end 140.48 + end 140.49 + 140.50 local comment = param.get("comment") 140.51 140.52 if comment ~= direct_voter.comment then
141.1 --- a/app/main/vote/list.lua Thu Jul 10 01:02:43 2014 +0200 141.2 +++ b/app/main/vote/list.lua Thu Jul 10 01:19:48 2014 +0200 141.3 @@ -21,69 +21,29 @@ 141.4 readonly = true 141.5 end 141.6 141.7 +if preview then 141.8 + readonly = true 141.9 +end 141.10 + 141.11 local submit_button_text = _"Finish voting" 141.12 +local edit_button_text = _"Edit again" 141.13 141.14 if issue.closed then 141.15 - submit_button_text = _"Update voting comment" 141.16 + submit_button_text = _"Save voting comment" 141.17 + edit_button_text = _"Edit voting comment" 141.18 end 141.19 141.20 +execute.view { 141.21 + module = "issue", view = "_head", params = { issue = issue } 141.22 +} 141.23 + 141.24 local direct_voter 141.25 141.26 if member then 141.27 direct_voter = DirectVoter:by_pk(issue.id, member.id) 141.28 - local str = _("Ballot of '#{member_name}' for issue ##{issue_id}", 141.29 - {member_name = string.format('<a href="%s">%s</a>', 141.30 - encode.url{ 141.31 - module = "member", 141.32 - view = "show", 141.33 - id = member.id, 141.34 - }, 141.35 - encode.html(member.name)), 141.36 - issue_id = string.format('<a href="%s">%s</a>', 141.37 - encode.url{ 141.38 - module = "issue", 141.39 - view = "show", 141.40 - id = issue.id, 141.41 - }, 141.42 - encode.html(tostring(issue.id))) 141.43 - } 141.44 - ) 141.45 - ui.raw_title(str) 141.46 else 141.47 member = app.session.member 141.48 - 141.49 direct_voter = DirectVoter:by_pk(issue.id, member.id) 141.50 - 141.51 - ui.title(_"Voting") 141.52 - 141.53 - ui.actions(function() 141.54 - ui.link{ 141.55 - text = _"Cancel", 141.56 - module = "issue", 141.57 - view = "show", 141.58 - id = issue.id 141.59 - } 141.60 - if direct_voter then 141.61 - slot.put(" · ") 141.62 - ui.link{ 141.63 - text = _"Discard voting", 141.64 - module = "vote", 141.65 - action = "update", 141.66 - params = { 141.67 - issue_id = issue.id, 141.68 - discard = true 141.69 - }, 141.70 - routing = { 141.71 - default = { 141.72 - mode = "redirect", 141.73 - module = "issue", 141.74 - view = "show", 141.75 - id = issue.id 141.76 - } 141.77 - } 141.78 - } 141.79 - end 141.80 - end) 141.81 end 141.82 141.83 141.84 @@ -144,10 +104,7 @@ 141.85 end 141.86 end 141.87 141.88 - 141.89 - 141.90 if not readonly then 141.91 - util.help("vote.list", _"Voting") 141.92 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/dragdrop.js"></script>') 141.93 slot.put('<script src="' .. request.get_relative_baseurl() .. 'static/js/voting.js"></script>') 141.94 end 141.95 @@ -179,321 +136,436 @@ 141.96 end 141.97 } 141.98 141.99 -ui.form{ 141.100 - record = direct_voter, 141.101 - attr = { 141.102 - id = "voting_form", 141.103 - class = readonly and "voting_form_readonly" or "voting_form_active" 141.104 - }, 141.105 - module = "vote", 141.106 - action = "update", 141.107 - params = { issue_id = issue.id }, 141.108 - content = function() 141.109 - if not readonly or preview then 141.110 - local scoring = param.get("scoring") 141.111 - if not scoring then 141.112 - for i, initiative in ipairs(initiatives) do 141.113 - local vote = initiative.vote 141.114 - if vote then 141.115 - tempvotings[initiative.id] = vote.grade 141.116 - else 141.117 - tempvotings[initiative.id] = 0 141.118 - end 141.119 - end 141.120 - local tempvotings_list = {} 141.121 - for key, val in pairs(tempvotings) do 141.122 - tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val) 141.123 - end 141.124 - if #tempvotings_list > 0 then 141.125 - scoring = table.concat(tempvotings_list, ";") 141.126 - else 141.127 - scoring = "" 141.128 - end 141.129 - end 141.130 - slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>') 141.131 - -- TODO abstrahieren 141.132 - ui.tag{ 141.133 - tag = "input", 141.134 - attr = { 141.135 - type = "submit", 141.136 - class = "voting_done1", 141.137 - value = submit_button_text 141.138 - } 141.139 +if issue.state == "finished_with_winner" 141.140 + or issue.state == "finished_without_winner" 141.141 +then 141.142 + 141.143 + local members_selector = Member:new_selector() 141.144 + :join("delegating_voter", nil, "delegating_voter.member_id = member.id") 141.145 + :add_where{ "delegating_voter.issue_id = ?", issue.id } 141.146 + :add_where{ "delegating_voter.delegate_member_ids[1] = ?", member.id } 141.147 + :add_field("delegating_voter.weight", "voter_weight") 141.148 + :join("issue", nil, "issue.id = delegating_voter.issue_id") 141.149 + 141.150 + ui.sidebar( "tab-members", function() 141.151 + ui.sidebarHead(function() 141.152 + ui.heading{ level = 2, content = _"Incoming delegations" } 141.153 + end) 141.154 + execute.view{ 141.155 + module = "member", 141.156 + view = "_list", 141.157 + params = { 141.158 + members_selector = members_selector, 141.159 + trustee = member, 141.160 + issue = issue, 141.161 + initiative = initiative, 141.162 + for_votes = true, no_filter = true, 141.163 + member_class = "sidebarRow sidebarRowNarrow", 141.164 } 141.165 + } 141.166 + end) 141.167 +end 141.168 + 141.169 + 141.170 +ui.section( function() 141.171 + 141.172 + ui.sectionHead( function() 141.173 + if preview then 141.174 + ui.heading { level = 1, content = _"Preview of voting ballot" } 141.175 + elseif readonly then 141.176 + local str = _("Ballot of '#{member_name}'", 141.177 + {member_name = string.format('<a href="%s">%s</a>', 141.178 + encode.url{ 141.179 + module = "member", 141.180 + view = "show", 141.181 + id = member.id, 141.182 + }, 141.183 + encode.html(member.name)) 141.184 + } 141.185 + ) 141.186 + ui.heading { level = 1, content = function () slot.put ( str ) end } 141.187 + else 141.188 + ui.heading { level = 1, content = _"Voting" } 141.189 end 141.190 - ui.container{ 141.191 - attr = { id = "voting" }, 141.192 + end ) 141.193 + 141.194 + ui.sectionRow( function() 141.195 + 141.196 + ui.form{ 141.197 + record = direct_voter, 141.198 + attr = { 141.199 + id = "voting_form", 141.200 + class = readonly and "voting_form_readonly" or "voting_form_active" 141.201 + }, 141.202 + module = "vote", 141.203 + action = "update", 141.204 + params = { issue_id = issue.id }, 141.205 content = function() 141.206 - local approval_index, disapproval_index = 0, 0 141.207 - for grade = max_grade, min_grade, -1 do 141.208 - local entries = sections[grade] 141.209 - local class 141.210 - if grade > 0 then 141.211 - class = "approval" 141.212 - elseif grade < 0 then 141.213 - class = "disapproval" 141.214 - else 141.215 - class = "abstention" 141.216 + if not readonly or preview then 141.217 + local scoring = param.get("scoring") 141.218 + if not scoring then 141.219 + for i, initiative in ipairs(initiatives) do 141.220 + local vote = initiative.vote 141.221 + if vote then 141.222 + tempvotings[initiative.id] = vote.grade 141.223 + else 141.224 + tempvotings[initiative.id] = 0 141.225 + end 141.226 + end 141.227 + local tempvotings_list = {} 141.228 + for key, val in pairs(tempvotings) do 141.229 + tempvotings_list[#tempvotings_list+1] = tostring(key) .. ":" .. tostring(val) 141.230 + end 141.231 + if #tempvotings_list > 0 then 141.232 + scoring = table.concat(tempvotings_list, ";") 141.233 + else 141.234 + scoring = "" 141.235 + end 141.236 end 141.237 - if 141.238 - #entries > 0 or 141.239 - (grade == 1 and not approval_used) or 141.240 - (grade == -1 and not disapproval_used) or 141.241 - grade == 0 141.242 - then 141.243 - ui.container{ 141.244 - attr = { class = class }, 141.245 - content = function() 141.246 - local heading 141.247 - if class == "approval" then 141.248 - approval_used = true 141.249 - approval_index = approval_index + 1 141.250 - if approval_count > 1 then 141.251 - if approval_index == 1 then 141.252 - if #entries == 1 then 141.253 - heading = _"Approval (first preference) [single entry]" 141.254 + slot.put('<input type="hidden" name="scoring" value="' .. scoring .. '"/>') 141.255 + end 141.256 + if preview then 141.257 + ui.heading{ level = 2, content = _"Your choice" } 141.258 + elseif not readonly then 141.259 + ui.heading{ level = 2, content = _"Make your choice by placing the initiatives" } 141.260 + end 141.261 + 141.262 + ui.container{ 141.263 + attr = { id = "voting" }, 141.264 + content = function() 141.265 + local approval_index, disapproval_index = 0, 0 141.266 + for grade = max_grade, min_grade, -1 do 141.267 + local entries = sections[grade] 141.268 + local class 141.269 + if grade > 0 then 141.270 + class = "approval" 141.271 + elseif grade < 0 then 141.272 + class = "disapproval" 141.273 + else 141.274 + class = "abstention" 141.275 + end 141.276 + if 141.277 + #entries > 0 or 141.278 + (grade == 1 and not approval_used) or 141.279 + (grade == -1 and not disapproval_used) or 141.280 + grade == 0 141.281 + then 141.282 + ui.container{ 141.283 + attr = { class = class }, 141.284 + content = function() 141.285 + local heading 141.286 + if class == "approval" then 141.287 + approval_used = true 141.288 + approval_index = approval_index + 1 141.289 + if approval_count > 1 then 141.290 + if approval_index == 1 then 141.291 + if #entries == 1 then 141.292 + heading = _"Approval (first preference) [single entry]" 141.293 + else 141.294 + heading = _"Approval (first preference) [many entries]" 141.295 + end 141.296 + elseif approval_index == 2 then 141.297 + if #entries == 1 then 141.298 + heading = _"Approval (second preference) [single entry]" 141.299 + else 141.300 + heading = _"Approval (second preference) [many entries]" 141.301 + end 141.302 + elseif approval_index == 3 then 141.303 + if #entries == 1 then 141.304 + heading = _"Approval (third preference) [single entry]" 141.305 + else 141.306 + heading = _"Approval (third preference) [many entries]" 141.307 + end 141.308 + else 141.309 + if #entries == 1 then 141.310 + heading = _"Approval (#th preference) [single entry]" 141.311 + else 141.312 + heading = _"Approval (#th preference) [many entries]" 141.313 + end 141.314 + end 141.315 else 141.316 - heading = _"Approval (first preference) [many entries]" 141.317 - end 141.318 - elseif approval_index == 2 then 141.319 - if #entries == 1 then 141.320 - heading = _"Approval (second preference) [single entry]" 141.321 - else 141.322 - heading = _"Approval (second preference) [many entries]" 141.323 + if #entries == 1 then 141.324 + heading = _"Approval [single entry]" 141.325 + else 141.326 + heading = _"Approval [many entries]" 141.327 + end 141.328 end 141.329 - elseif approval_index == 3 then 141.330 - if #entries == 1 then 141.331 - heading = _"Approval (third preference) [single entry]" 141.332 + elseif class == "abstention" then 141.333 + if #entries == 1 then 141.334 + heading = _"Abstention [single entry]" 141.335 + else 141.336 + heading = _"Abstention [many entries]" 141.337 + end 141.338 + elseif class == "disapproval" then 141.339 + disapproval_used = true 141.340 + disapproval_index = disapproval_index + 1 141.341 + if disapproval_count > disapproval_index + 1 then 141.342 + if #entries == 1 then 141.343 + heading = _"Disapproval (prefer to lower blocks) [single entry]" 141.344 + else 141.345 + heading = _"Disapproval (prefer to lower blocks) [many entries]" 141.346 + end 141.347 + elseif disapproval_count == 2 and disapproval_index == 1 then 141.348 + if #entries == 1 then 141.349 + heading = _"Disapproval (prefer to lower block) [single entry]" 141.350 + else 141.351 + heading = _"Disapproval (prefer to lower block) [many entries]" 141.352 + end 141.353 + elseif disapproval_index == disapproval_count - 1 then 141.354 + if #entries == 1 then 141.355 + heading = _"Disapproval (prefer to last block) [single entry]" 141.356 + else 141.357 + heading = _"Disapproval (prefer to last block) [many entries]" 141.358 + end 141.359 else 141.360 - heading = _"Approval (third preference) [many entries]" 141.361 - end 141.362 - else 141.363 - if #entries == 1 then 141.364 - heading = _"Approval (#th preference) [single entry]" 141.365 - else 141.366 - heading = _"Approval (#th preference) [many entries]" 141.367 + if #entries == 1 then 141.368 + heading = _"Disapproval [single entry]" 141.369 + else 141.370 + heading = _"Disapproval [many entries]" 141.371 + end 141.372 end 141.373 end 141.374 - else 141.375 - if #entries == 1 then 141.376 - heading = _"Approval [single entry]" 141.377 - else 141.378 - heading = _"Approval [many entries]" 141.379 - end 141.380 - end 141.381 - elseif class == "abstention" then 141.382 - if #entries == 1 then 141.383 - heading = _"Abstention [single entry]" 141.384 - else 141.385 - heading = _"Abstention [many entries]" 141.386 - end 141.387 - elseif class == "disapproval" then 141.388 - disapproval_used = true 141.389 - disapproval_index = disapproval_index + 1 141.390 - if disapproval_count > disapproval_index + 1 then 141.391 - if #entries == 1 then 141.392 - heading = _"Disapproval (prefer to lower blocks) [single entry]" 141.393 - else 141.394 - heading = _"Disapproval (prefer to lower blocks) [many entries]" 141.395 - end 141.396 - elseif disapproval_count == 2 and disapproval_index == 1 then 141.397 - if #entries == 1 then 141.398 - heading = _"Disapproval (prefer to lower block) [single entry]" 141.399 - else 141.400 - heading = _"Disapproval (prefer to lower block) [many entries]" 141.401 - end 141.402 - elseif disapproval_index == disapproval_count - 1 then 141.403 - if #entries == 1 then 141.404 - heading = _"Disapproval (prefer to last block) [single entry]" 141.405 - else 141.406 - heading = _"Disapproval (prefer to last block) [many entries]" 141.407 - end 141.408 - else 141.409 - if #entries == 1 then 141.410 - heading = _"Disapproval [single entry]" 141.411 - else 141.412 - heading = _"Disapproval [many entries]" 141.413 - end 141.414 - end 141.415 - end 141.416 - ui.tag { 141.417 - tag = "div", 141.418 - attr = { class = "cathead" }, 141.419 - content = heading 141.420 - } 141.421 - for i, initiative in ipairs(entries) do 141.422 - ui.container{ 141.423 - attr = { 141.424 - class = "movable", 141.425 - id = "entry_" .. tostring(initiative.id) 141.426 - }, 141.427 - content = function() 141.428 - local initiators_selector = initiative:get_reference_selector("initiating_members") 141.429 - :add_where("accepted") 141.430 - local initiators = initiators_selector:exec() 141.431 - local initiator_names = {} 141.432 - for i, initiator in ipairs(initiators) do 141.433 - initiator_names[#initiator_names+1] = initiator.name 141.434 - end 141.435 - local initiator_names_string = table.concat(initiator_names, ", ") 141.436 + ui.tag { 141.437 + tag = "div", 141.438 + attr = { class = "cathead" }, 141.439 + content = heading 141.440 + } 141.441 + for i, initiative in ipairs(entries) do 141.442 ui.container{ 141.443 - attr = { style = "float: right; position: relative;" }, 141.444 + attr = { 141.445 + class = "movable", 141.446 + id = "entry_" .. tostring(initiative.id) 141.447 + }, 141.448 content = function() 141.449 - ui.link{ 141.450 - attr = { class = "clickable" }, 141.451 - content = _"Show", 141.452 - module = "initiative", 141.453 - view = "show", 141.454 - id = initiative.id 141.455 - } 141.456 - slot.put(" ") 141.457 - ui.link{ 141.458 - attr = { class = "clickable", target = "_blank" }, 141.459 - content = _"(new window)", 141.460 - module = "initiative", 141.461 - view = "show", 141.462 - id = initiative.id 141.463 + local initiators_selector = initiative:get_reference_selector("initiating_members") 141.464 + :add_where("accepted") 141.465 + local initiators = initiators_selector:exec() 141.466 + local initiator_names = {} 141.467 + for i, initiator in ipairs(initiators) do 141.468 + initiator_names[#initiator_names+1] = initiator.name 141.469 + end 141.470 + local initiator_names_string = table.concat(initiator_names, ", ") 141.471 + ui.container{ 141.472 + attr = { style = "float: right; position: relative;" }, 141.473 + content = function() 141.474 + ui.link{ 141.475 + attr = { class = "clickable" }, 141.476 + content = _"Show", 141.477 + module = "initiative", 141.478 + view = "show", 141.479 + id = initiative.id 141.480 + } 141.481 + slot.put(" ") 141.482 + ui.link{ 141.483 + attr = { class = "clickable", target = "_blank" }, 141.484 + content = _"(new window)", 141.485 + module = "initiative", 141.486 + view = "show", 141.487 + id = initiative.id 141.488 + } 141.489 + if not readonly then 141.490 + slot.put(" ") 141.491 + ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" } 141.492 + end 141.493 + end 141.494 } 141.495 if not readonly then 141.496 - slot.put(" ") 141.497 - ui.image{ attr = { class = "grabber" }, static = "icons/grabber.png" } 141.498 - end 141.499 - end 141.500 - } 141.501 - if not readonly then 141.502 - ui.container{ 141.503 - attr = { style = "float: left; position: relative;" }, 141.504 - content = function() 141.505 - ui.tag{ 141.506 - tag = "input", 141.507 - attr = { 141.508 - onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);", 141.509 - name = "move_up_" .. tostring(initiative.id), 141.510 - class = not disabled and "clickable" or nil, 141.511 - type = "image", 141.512 - src = encode.url{ static = "icons/move_up.png" }, 141.513 - alt = _"Move up" 141.514 - } 141.515 - } 141.516 - slot.put(" ") 141.517 - ui.tag{ 141.518 - tag = "input", 141.519 - attr = { 141.520 - onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);", 141.521 - name = "move_down_" .. tostring(initiative.id), 141.522 - class = not disabled and "clickable" or nil, 141.523 - type = "image", 141.524 - src = encode.url{ static = "icons/move_down.png" }, 141.525 - alt = _"Move down" 141.526 - } 141.527 - } 141.528 - slot.put(" ") 141.529 - end 141.530 - } 141.531 - end 141.532 - ui.container{ 141.533 - content = function() 141.534 - ui.tag{ content = "i" .. initiative.id .. ": " } 141.535 - ui.tag{ content = initiative.shortened_name } 141.536 - slot.put("<br />") 141.537 - for i, initiator in ipairs(initiators) do 141.538 - ui.link{ 141.539 - attr = { class = "clickable" }, 141.540 - content = function () 141.541 - execute.view{ 141.542 - module = "member_image", 141.543 - view = "_show", 141.544 - params = { 141.545 - member = initiator, 141.546 - image_type = "avatar", 141.547 - show_dummy = true, 141.548 - class = "micro_avatar", 141.549 - popup_text = text 141.550 + ui.container{ 141.551 + attr = { style = "float: left; position: relative;" }, 141.552 + content = function() 141.553 + ui.tag{ 141.554 + tag = "input", 141.555 + attr = { 141.556 + onclick = "if (jsFail) return true; voting_moveUp(this.parentNode.parentNode); return(false);", 141.557 + name = "move_up_" .. tostring(initiative.id), 141.558 + class = not disabled and "clickable" or nil, 141.559 + type = "image", 141.560 + src = encode.url{ static = "icons/move_up.png" }, 141.561 + alt = _"Move up" 141.562 + } 141.563 + } 141.564 + slot.put(" ") 141.565 + ui.tag{ 141.566 + tag = "input", 141.567 + attr = { 141.568 + onclick = "if (jsFail) return true; voting_moveDown(this.parentNode.parentNode); return(false);", 141.569 + name = "move_down_" .. tostring(initiative.id), 141.570 + class = not disabled and "clickable" or nil, 141.571 + type = "image", 141.572 + src = encode.url{ static = "icons/move_down.png" }, 141.573 + alt = _"Move down" 141.574 } 141.575 } 141.576 - end, 141.577 - module = "member", view = "show", id = initiator.id 141.578 + slot.put(" ") 141.579 + end 141.580 } 141.581 - slot.put(" ") 141.582 - ui.tag{ content = initiator.name } 141.583 - slot.put(" ") 141.584 end 141.585 + ui.container{ 141.586 + content = function() 141.587 + ui.tag{ content = "i" .. initiative.id .. ": " } 141.588 + ui.tag{ content = initiative.shortened_name } 141.589 + slot.put("<br />") 141.590 + for i, initiator in ipairs(initiators) do 141.591 + ui.link{ 141.592 + attr = { class = "clickable" }, 141.593 + content = function () 141.594 + execute.view{ 141.595 + module = "member_image", 141.596 + view = "_show", 141.597 + params = { 141.598 + member = initiator, 141.599 + image_type = "avatar", 141.600 + show_dummy = true, 141.601 + class = "micro_avatar", 141.602 + popup_text = text 141.603 + } 141.604 + } 141.605 + end, 141.606 + module = "member", view = "show", id = initiator.id 141.607 + } 141.608 + slot.put(" ") 141.609 + ui.tag{ content = initiator.name } 141.610 + slot.put(" ") 141.611 + end 141.612 + end 141.613 + } 141.614 end 141.615 } 141.616 end 141.617 + end 141.618 + } 141.619 + end 141.620 + end 141.621 + end 141.622 + } 141.623 + if app.session.member_id and preview then 141.624 + local formatting_engine = param.get("formatting_engine") or config.enforce_formatting_engine 141.625 + local comment = param.get("comment") 141.626 + if comment and #comment > 0 then 141.627 + local rendered_comment = format.wiki_text(comment, formatting_engine) 141.628 + ui.heading{ level = "2", content = _"Voting comment" } 141.629 + ui.container { attr = { class = "member_statement" }, content = function() 141.630 + slot.put(rendered_comment) 141.631 + end } 141.632 + slot.put("<br />") 141.633 + end 141.634 + end 141.635 + if (readonly or direct_voter and direct_voter.comment) and not preview and not (app.session.member_id == member.id) then 141.636 + local text 141.637 + if direct_voter and direct_voter.comment_changed then 141.638 + text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) }) 141.639 + elseif direct_voter and direct_voter.comment then 141.640 + text = _"Voting comment" 141.641 + end 141.642 + if text then 141.643 + ui.heading{ level = "2", content = text } 141.644 + end 141.645 + if direct_voter and direct_voter.comment then 141.646 + local rendered_comment = direct_voter:get_content('html') 141.647 + ui.container { attr = { class = "member_statement" }, content = function() 141.648 + slot.put(rendered_comment) 141.649 + end } 141.650 + slot.put("<br />") 141.651 + end 141.652 + end 141.653 + if app.session.member_id and app.session.member_id == member.id then 141.654 + if (not readonly or direct_voter) and not preview then 141.655 + ui.container{ content = function() 141.656 + if not config.enforce_formatting_engine then 141.657 + ui.field.select{ 141.658 + label = _"Wiki engine for statement", 141.659 + name = "formatting_engine", 141.660 + foreign_records = config.formatting_engines, 141.661 + attr = {id = "formatting_engine"}, 141.662 + foreign_id = "id", 141.663 + foreign_name = "name", 141.664 + value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine 141.665 + } 141.666 + end 141.667 + ui.heading { level = 2, content = _"Voting comment (optional)" } 141.668 + ui.field.text{ 141.669 + name = "comment", 141.670 + multiline = true, 141.671 + value = param.get("comment") or direct_voter and direct_voter.comment, 141.672 + attr = { style = "height: 10ex; width: 100%;" }, 141.673 + } 141.674 + end } 141.675 + end 141.676 + 141.677 + if preview then 141.678 + if not config.enforce_formatting_engine then 141.679 + ui.field.hidden{ name = "formatting_engine", value = param.get("formatting_engine") } 141.680 + end 141.681 + ui.field.hidden{ name = "comment", value = param.get("comment") or direct_voter and direct_voter.comment } 141.682 + end 141.683 + 141.684 + if not readonly or direct_voter or preview then 141.685 + ui.container{ content = function() 141.686 + if preview then 141.687 + slot.put(" ") 141.688 + ui.tag{ 141.689 + tag = "input", 141.690 + attr = { 141.691 + type = "submit", 141.692 + class = "btn btn-default", 141.693 + name = issue.closed and "update_comment" or nil, 141.694 + value = submit_button_text -- finish voting / update comment 141.695 } 141.696 - end 141.697 + } 141.698 end 141.699 - } 141.700 + if not preview then 141.701 + ui.tag{ 141.702 + tag = "input", 141.703 + attr = { 141.704 + type = "submit", 141.705 + name = "preview", 141.706 + class = "btn btn-default", 141.707 + value = _"Preview", 141.708 + } 141.709 + } 141.710 + else 141.711 + slot.put(" ") 141.712 + ui.tag{ 141.713 + tag = "input", 141.714 + attr = { 141.715 + type = "submit", 141.716 + name = "edit", 141.717 + class = "btn-link", 141.718 + value = edit_button_text, 141.719 + } 141.720 + } 141.721 + end 141.722 + end } 141.723 end 141.724 end 141.725 end 141.726 } 141.727 - if app.session.member_id and preview then 141.728 - local formatting_engine = param.get("formatting_engine") 141.729 - local comment = param.get("comment") 141.730 - local rendered_comment = format.wiki_text(comment, formatting_engine) 141.731 - slot.put(rendered_comment) 141.732 - end 141.733 - if (readonly or direct_voter and direct_voter.comment) and not preview then 141.734 - local text 141.735 - if direct_voter and direct_voter.comment_changed then 141.736 - text = _("Voting comment (last updated: #{timestamp})", { timestamp = format.timestamp(direct_voter.comment_changed) }) 141.737 - elseif direct_voter and direct_voter.comment then 141.738 - text = _"Voting comment" 141.739 - end 141.740 - if text then 141.741 - ui.heading{ level = "2", content = text } 141.742 - end 141.743 - if direct_voter and direct_voter.comment then 141.744 - local rendered_comment = direct_voter:get_content('html') 141.745 - ui.container{ attr = { class = "member_statement" }, content = function() 141.746 - slot.put(rendered_comment) 141.747 - end } 141.748 - slot.put("<br />") 141.749 - end 141.750 + slot.put("<br />") 141.751 + ui.link{ 141.752 + text = _"Cancel", 141.753 + module = "issue", 141.754 + view = "show", 141.755 + id = issue.id 141.756 + } 141.757 + if direct_voter then 141.758 + slot.put(" | ") 141.759 + ui.link { 141.760 + module = "vote", action = "update", 141.761 + params = { 141.762 + issue_id = issue.id, 141.763 + discard = true 141.764 + }, 141.765 + routing = { 141.766 + default = { 141.767 + mode = "redirect", 141.768 + module = "issue", 141.769 + view = "show", 141.770 + id = issue.id 141.771 + } 141.772 + }, 141.773 + text = _"Discard my vote" 141.774 + } 141.775 end 141.776 - if app.session.member_id and app.session.member_id == member.id then 141.777 - if not readonly or direct_voter then 141.778 - ui.field.hidden{ name = "update_comment", value = param.get("update_comment") or issue.closed and "1" } 141.779 - ui.field.select{ 141.780 - label = _"Wiki engine for statement", 141.781 - name = "formatting_engine", 141.782 - foreign_records = { 141.783 - { id = "rocketwiki", name = "RocketWiki" }, 141.784 - { id = "compat", name = _"Traditional wiki syntax" } 141.785 - }, 141.786 - attr = {id = "formatting_engine"}, 141.787 - foreign_id = "id", 141.788 - foreign_name = "name", 141.789 - value = param.get("formatting_engine") or direct_voter and direct_voter.formatting_engine 141.790 - } 141.791 - ui.field.text{ 141.792 - label = _"Voting comment (optional)", 141.793 - name = "comment", 141.794 - multiline = true, 141.795 - value = param.get("comment") or direct_voter and direct_voter.comment, 141.796 - attr = { style = "height: 20ex;" }, 141.797 - } 141.798 - ui.submit{ 141.799 - name = "preview", 141.800 - value = _"Preview voting comment", 141.801 - attr = { class = "preview" } 141.802 - } 141.803 - end 141.804 - if not readonly or preview or direct_voter then 141.805 - slot.put(" ") 141.806 - ui.tag{ 141.807 - tag = "input", 141.808 - attr = { 141.809 - type = "submit", 141.810 - class = "voting_done2", 141.811 - value = submit_button_text 141.812 - } 141.813 - } 141.814 - end 141.815 - end 141.816 - end 141.817 -} 141.818 141.819 - 141.820 + end ) 141.821 +end ) 141.822 \ No newline at end of file
142.1 --- a/app/main/vote/show_incoming.lua Thu Jul 10 01:02:43 2014 +0200 142.2 +++ b/app/main/vote/show_incoming.lua Thu Jul 10 01:19:48 2014 +0200 142.3 @@ -1,5 +1,20 @@ 142.4 -local initiative = Initiative:by_id(param.get("initiative_id", atom.integer)) 142.5 -local issue = initiative.issue 142.6 +local initiative = Initiative:by_id(param.get("initiative_id")) 142.7 + 142.8 +local issue 142.9 + 142.10 +if initiative then 142.11 + issue = initiative.issue 142.12 +else 142.13 + issue = Issue:by_id(param.get("issue_id")) 142.14 +end 142.15 + 142.16 +if app.session.member_id then 142.17 + if initiative then 142.18 + initiative:load_everything_for_member_id(app.session.member.id) 142.19 + end 142.20 + issue:load_everything_for_member_id(app.session.member.id) 142.21 +end 142.22 + 142.23 local member = Member:by_id(param.get("member_id", atom.integer)) 142.24 142.25 local members_selector = Member:new_selector() 142.26 @@ -9,13 +24,55 @@ 142.27 :add_field("delegating_voter.weight", "voter_weight") 142.28 :join("issue", nil, "issue.id = delegating_voter.issue_id") 142.29 142.30 + 142.31 execute.view{ 142.32 - module = "member", 142.33 - view = "_list", 142.34 - params = { 142.35 - members_selector = members_selector, 142.36 - initiative = initiative, 142.37 - trustee = member, 142.38 - for_votes = true 142.39 + module = "issue", view = "_head", params = { 142.40 + issue = issue, initiative = initiative 142.41 + } 142.42 +} 142.43 + 142.44 +execute.view{ module = "issue", view = "_sidebar_state", params = { 142.45 + issue = issue, 142.46 +} } 142.47 + 142.48 +execute.view { 142.49 + module = "issue", view = "_sidebar_issue", params = { 142.50 + issue = issue, 142.51 + highlight_initiative_id = initiative and initiative.id or nil, 142.52 + } 142.53 +} 142.54 + 142.55 +execute.view { 142.56 + module = "issue", view = "_sidebar_whatcanido", params = { 142.57 + issue = issue 142.58 } 142.59 -} 142.60 \ No newline at end of file 142.61 +} 142.62 + 142.63 +execute.view { 142.64 + module = "issue", view = "_sidebar_members", params = { 142.65 + issue = issue, 142.66 + initiative = initiative 142.67 + } 142.68 +} 142.69 + 142.70 + 142.71 +ui.section( function() 142.72 + 142.73 + ui.sectionHead( function() 142.74 + ui.heading{ level = 1, content = _("Incoming delegations for '#{member}'", { member = member.name }) } 142.75 + end) 142.76 + 142.77 + execute.view{ 142.78 + module = "member", 142.79 + view = "_list", 142.80 + params = { 142.81 + members_selector = members_selector, 142.82 + trustee = member, 142.83 + issue = issue, 142.84 + initiative = initiative, 142.85 + for_votes = true, no_filter = true, 142.86 + 142.87 + } 142.88 + } 142.89 + 142.90 +end )
143.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 143.2 +++ b/config/devel.lua Thu Jul 10 01:19:48 2014 +0200 143.3 @@ -0,0 +1,288 @@ 143.4 +-- ======================================================================== 143.5 +-- MANDATORY (MUST BE CAREFULLY CHECKED AND PROPERLY SET!) 143.6 +-- ======================================================================== 143.7 + 143.8 +-- Name of this instance, defaults to name of config file 143.9 +-- ------------------------------------------------------------------------ 143.10 +config.instance_name = "Public Software Group e.V." 143.11 + 143.12 + 143.13 +-- Information about service provider (HTML) 143.14 +-- ------------------------------------------------------------------------ 143.15 +config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany" 143.16 + 143.17 + 143.18 +-- A HTML formatted text the user has to accept while registering 143.19 +-- ------------------------------------------------------------------------ 143.20 +config.use_terms = "<h1>Terms of Use</h1><p>Insert terms here</p>" 143.21 + 143.22 + 143.23 +-- Checkbox(es) the user has to accept while registering 143.24 +-- ------------------------------------------------------------------------ 143.25 +config.use_terms_checkboxes = { 143.26 + { 143.27 + name = "terms_of_use_v1", 143.28 + html = "I accept the terms of use.", 143.29 + not_accepted_error = "You have to accept the terms of use to be able to register." 143.30 + }, 143.31 +-- { 143.32 +-- name = "extra_terms_of_use_v1", 143.33 +-- html = "I accept the extra terms of use.", 143.34 +-- not_accepted_error = "You have to accept the extra terms of use to be able to register." 143.35 +-- } 143.36 +} 143.37 + 143.38 + 143.39 +-- Absolute base url of application 143.40 +-- ------------------------------------------------------------------------ 143.41 +config.absolute_base_url = "http://192.168.1.34/lf3/" 143.42 + 143.43 + 143.44 +-- Connection information for the LiquidFeedback database 143.45 +-- ------------------------------------------------------------------------ 143.46 +config.database = { engine='postgresql', dbname='liquid_feedback' } 143.47 +config.database = { engine='postgresql', dbname='lftest' } 143.48 + 143.49 + 143.50 +-- Location of the rocketwiki binaries 143.51 +-- ------------------------------------------------------------------------ 143.52 +config.enforce_formatting_engine = "markdown2" 143.53 + 143.54 +config.formatting_engines = { 143.55 + { id = "markdown2", 143.56 + name = "python-markdown2", 143.57 + executable = "markdown2", 143.58 + args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'}, 143.59 + remove_images = true 143.60 + }, 143.61 + { id = "markdown_py", 143.62 + name = "Python Markdown", 143.63 + executable = "markdown_py", 143.64 + args = {'-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'}, 143.65 + remove_images = true 143.66 + }, 143.67 + { id = "rocketwiki", 143.68 + name = "RocketWiki", 143.69 + executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb", 143.70 + remove_images = false 143.71 + }, 143.72 + { id = "compat", 143.73 + name = "Traditional WIKI syntax", 143.74 + executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat", 143.75 + remove_images = false 143.76 + } 143.77 +} 143.78 + 143.79 +-- Public access level 143.80 +-- ------------------------------------------------------------------------ 143.81 +-- Available options: 143.82 +-- "none" 143.83 +-- -> Closed user group, no public access at all 143.84 +-- (except login/registration/password reset) 143.85 +-- "anonymous" 143.86 +-- -> Shows only initiative/suggestions texts and aggregated 143.87 +-- supporter/voter counts 143.88 +-- "authors_pseudonymous" 143.89 +-- -> Like anonymous, but shows screen names of authors 143.90 +-- "all_pseudonymous" 143.91 +-- -> Show everything a member can see, except profile pages 143.92 +-- "everything" 143.93 +-- -> Show everything a member can see, including profile pages 143.94 +-- ------------------------------------------------------------------------ 143.95 +config.public_access = "all_pseudonymous" 143.96 + 143.97 + 143.98 + 143.99 +-- ======================================================================== 143.100 +-- OPTIONAL 143.101 +-- Remove leading -- to use a option 143.102 +-- ======================================================================== 143.103 + 143.104 +-- List of enabled languages, defaults to available languages 143.105 +-- ------------------------------------------------------------------------ 143.106 +-- config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-TW' } 143.107 + 143.108 +-- Default language, defaults to "en" 143.109 +-- ------------------------------------------------------------------------ 143.110 +-- config.default_lang = "de" 143.111 + 143.112 +-- after how long is a user considered inactive and the trustee will see warning, 143.113 +-- notation is according to postgresql intervals, default: no warning at all 143.114 +-- ------------------------------------------------------------------------ 143.115 +config.delegation_warning_time = '1 hour' 143.116 + 143.117 +-- after which time a user is suggested to (_soft) or forced to (_hard) 143.118 +-- confirm unit and area delegations. default: no confirmation at all 143.119 +-- ------------------------------------------------------------------------ 143.120 +-- config.check_delegations_interval_hard = "1 day" 143.121 +-- config.check_delegations_interval_soft = "3 seconds" 143.122 + 143.123 +-- default options should be checked when confirming delegations 143.124 +-- options: "confirm", "revoke" and "none" 143.125 +-- ------------------------------------------------------------------------ 143.126 +-- config.check_delegations_default = "confirm" 143.127 + 143.128 +-- Prefix of all automatic mails, defaults to "[Liquid Feedback] " 143.129 +-- ------------------------------------------------------------------------ 143.130 +-- config.mail_subject_prefix = "[LiquidFeedback] " 143.131 + 143.132 +-- Sender of all automatic mails, defaults to system defaults 143.133 +-- ------------------------------------------------------------------------ 143.134 +-- config.mail_envelope_from = "liquidfeedback@example.com" 143.135 +-- config.mail_from = { name = "LiquidFeedback", address = "liquidfeedback@example.com" } 143.136 +-- config.mail_reply_to = { name = "Support", address = "support@example.com" } 143.137 + 143.138 +-- Configuration of password hashing algorithm (defaults to "crypt_sha512") 143.139 +-- ------------------------------------------------------------------------ 143.140 +-- config.password_hash_algorithm = "crypt_sha512" 143.141 +-- config.password_hash_algorithm = "crypt_sha256" 143.142 +-- config.password_hash_algorithm = "crypt_md5" 143.143 + 143.144 +-- Number of rounds for crypt_sha* algorithms, minimum and maximum 143.145 +-- (defaults to minimum 10000 and maximum 20000) 143.146 +-- ------------------------------------------------------------------------ 143.147 +-- config.password_hash_min_rounds = 10000 143.148 +-- config.password_hash_max_rounds = 20000 143.149 + 143.150 +-- Supply custom url for avatar/photo delivery 143.151 +-- ------------------------------------------------------------------------ 143.152 +-- config.fastpath_url_func = nil 143.153 + 143.154 +-- Local directory for database dumps offered for download 143.155 +-- ------------------------------------------------------------------------ 143.156 +-- config.download_dir = nil 143.157 + 143.158 +-- Special use terms for database dump download 143.159 +-- ------------------------------------------------------------------------ 143.160 +-- config.download_use_terms = "=== Download use terms ===\n" 143.161 + 143.162 +-- Use custom image conversion, defaults to ImageMagick's convert 143.163 +-- ------------------------------------------------------------------------ 143.164 +--config.member_image_content_type = "image/jpeg" 143.165 +--config.member_image_convert_func = { 143.166 +-- avatar = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "48x48", "jpeg:-") end, 143.167 +-- photo = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end 143.168 +--} 143.169 + 143.170 +config.member_image_content_type = "image/jpeg" 143.171 +config.member_image_convert_func = { 143.172 + avatar = function(data) return extos.pfilter(data, "convert", 143.173 + "jpeg:-", 143.174 + "-set", "option:distort:viewport", 143.175 + "%[fx:min(w,h)]x%[fx:min(w,h)]+%[fx:max((w-h)/2,0)]+%[fx:max((h-w)/2,0)]", 143.176 + "-filter", "point", 143.177 + "-distort", "SRT", "0", 143.178 + "+repage", 143.179 + "-define", "filter:filter=Sinc", 143.180 + "-define", "filter:window=Jinc", 143.181 + "-define", "filter:lobes=3", 143.182 + "-thumbnail", "48x48", 143.183 + "jpeg:-" 143.184 + ) end, 143.185 + photo = function(data) return extos.pfilter(data, "convert", 143.186 + "jpeg:-", 143.187 + "-define", "filter:filter=Sinc", 143.188 + "-define", "filter:window=Jinc", 143.189 + "-define", "filter:lobes=3", 143.190 + "-thumbnail", "240x240", 143.191 + "jpeg:-" 143.192 + ) end 143.193 +} 143.194 + 143.195 + 143.196 +-- Display a html formatted public message of the day 143.197 +-- ------------------------------------------------------------------------ 143.198 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>" 143.199 + 143.200 +-- Display a html formatted internal message of the day 143.201 +-- ------------------------------------------------------------------------ 143.202 +-- config.motd_intern = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>" 143.203 + 143.204 +-- Automatic issue related discussion URL 143.205 +-- ------------------------------------------------------------------------ 143.206 +-- config.issue_discussion_url_func = function(issue) 143.207 +-- return "http://example.com/discussion/issue_" .. tostring(issue.id) 143.208 +-- end 143.209 + 143.210 +-- Configuration of "tell others" 143.211 +-- ------------------------------------------------------------------------ 143.212 +config.tell_others = { 143.213 + initiative = function (initiative) 143.214 + local text = "i" .. initiative.id .. ": " .. initiative.name .. " " .. request.get_absolute_baseurl() .. "initiative/" .. initiative.id .. ".html" 143.215 + return { 143.216 + { content = "tweet this initiative", external = "https://twitter.com/intent/tweet?text=" .. encode.url_part(text) }, 143.217 + { content = "send link with e-mail", external = "mailto:?subject=" .. encode.url_part(initiative.display_name) .. "&body=" .. encode.url_part(text) } 143.218 + } 143.219 + end 143.220 +} 143.221 + 143.222 +-- Integration of Etherpad, disabled by default 143.223 +-- ------------------------------------------------------------------------ 143.224 +--config.etherpad = { 143.225 +-- base_url = "http://example.com:9001/", 143.226 +-- api_base = "http://localhost:9001/", 143.227 +-- api_key = "mysecretapikey", 143.228 +-- group_id = "mygroupname", 143.229 +-- cookie_path = "/" 143.230 +--} 143.231 + 143.232 +-- Free timings, may be used together with polling policies 143.233 +-- ------------------------------------------------------------------------ 143.234 +-- This example expects a date string entered in the free timing field 143.235 +-- by the user creating a poll, interpreting it as target date for then 143.236 +-- poll and splits the remainig time at the ratio of 4:1:2 143.237 +-- Please note, polling policies never have an admission phase 143.238 + 143.239 + 143.240 +config.free_timing = { 143.241 + calculate_func = function(policy, timing_string) 143.242 + function interval_by_seconds(secs) 143.243 + local secs_per_day = 60 * 60 * 24 143.244 + local days 143.245 + days = math.floor(secs / secs_per_day) 143.246 + secs = secs - days * secs_per_day 143.247 + return days .. " days " .. secs .. " seconds" 143.248 + end 143.249 + local target_date = parse.date(timing_string, atom.date) 143.250 + if not target_date then 143.251 + return false 143.252 + end 143.253 + local target_timestamp = target_date.midday 143.254 + local now = atom.timestamp:get_current() 143.255 + trace.debug(target_timestamp, now) 143.256 + local duration = target_timestamp - now 143.257 + if duration < 0 then 143.258 + return false 143.259 + end 143.260 + return { 143.261 + discussion = interval_by_seconds(duration / 7 * 4), 143.262 + verification = interval_by_seconds(duration / 7 * 1), 143.263 + voting = interval_by_seconds(duration / 7 * 2) 143.264 + } 143.265 + end, 143.266 + available_func = function(policy) 143.267 + return { 143.268 + { name = "End of 2013", id = '2013-12-31' }, 143.269 + { name = "End of 2014", id = '2014-12-31' }, 143.270 + { name = "End of 2015", id = '2015-12-31' } 143.271 + } 143.272 + end 143.273 +} 143.274 + 143.275 + 143.276 +config.enable_debug_trace = true 143.277 + 143.278 +-- WebMCP accelerator 143.279 +-- uncomment the following two lines to use C implementations of chosen 143.280 +-- functions and to disable garbage collection during the request, to 143.281 +-- increase speed: 143.282 +-- ------------------------------------------------------------------------ 143.283 +-- require 'webmcp_accelerator' 143.284 +-- if cgi then collectgarbage("stop") end 143.285 + 143.286 + 143.287 +-- ======================================================================== 143.288 +-- Do main initialisation (DO NOT REMOVE FOLLOWING SECTION) 143.289 +-- ======================================================================== 143.290 + 143.291 +execute.config("init")
144.1 --- a/config/example.lua Thu Jul 10 01:02:43 2014 +0200 144.2 +++ b/config/example.lua Thu Jul 10 01:19:48 2014 +0200 144.3 @@ -12,9 +12,9 @@ 144.4 config.app_service_provider = "Snake Oil<br/>10000 Berlin<br/>Germany" 144.5 144.6 144.7 --- A rocketwiki formatted text the user has to accept while registering 144.8 +-- A HTML formatted text the user has to accept while registering 144.9 -- ------------------------------------------------------------------------ 144.10 -config.use_terms = "=== Terms of Use ===" 144.11 +config.use_terms = "<h1>Terms of Use</h1><p>Insert terms here</p>" 144.12 144.13 144.14 -- Checkbox(es) the user has to accept while registering 144.15 @@ -45,9 +45,29 @@ 144.16 144.17 -- Location of the rocketwiki binaries 144.18 -- ------------------------------------------------------------------------ 144.19 -config.formatting_engine_executeables = { 144.20 - rocketwiki= "/opt/rocketwiki-lqfb/rocketwiki-lqfb", 144.21 - compat = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat" 144.22 +config.enforce_formatting_engine = "markdown2" 144.23 +config.formatting_engines = { 144.24 + { id = "markdown2", 144.25 + name = "python-markdown2", 144.26 + executable = "markdown2", 144.27 + args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'}, 144.28 + remove_images = true 144.29 + }, 144.30 + { id = "markdown_py", 144.31 + name = "Python Markdown", 144.32 + executable = "markdown_py", 144.33 + args = {'-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'}, 144.34 + remove_images = true 144.35 + }, 144.36 + { id = "rocketwiki", 144.37 + name = "RocketWiki", 144.38 + executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb" 144.39 + }, 144.40 + { id = "compat", 144.41 + name = "Traditional WIKI syntax", 144.42 + executable = "/opt/rocketwiki-lqfb/rocketwiki-lqfb-compat" 144.43 + }, 144.44 + 144.45 } 144.46 144.47 144.48 @@ -143,9 +163,13 @@ 144.49 -- photo = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end 144.50 --} 144.51 144.52 --- Display a public message of the day 144.53 +-- Display a html formatted public message of the day 144.54 -- ------------------------------------------------------------------------ 144.55 --- config.motd_public = "===Message of the day===\nThe MOTD is formatted with rocket wiki" 144.56 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>" 144.57 + 144.58 +-- Display a html formatted internal message of the day 144.59 +-- ------------------------------------------------------------------------ 144.60 +-- config.motd_intern = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>" 144.61 144.62 -- Automatic issue related discussion URL 144.63 -- ------------------------------------------------------------------------
145.1 --- a/config/init.lua Thu Jul 10 01:02:43 2014 +0200 145.2 +++ b/config/init.lua Thu Jul 10 01:19:48 2014 +0200 145.3 @@ -3,7 +3,7 @@ 145.4 -- (except when you really know what you are doing!) 145.5 -- ======================================================================== 145.6 145.7 -config.app_version = "2.2.6" 145.8 +config.app_version = "3.0.0" 145.9 145.10 if not config.password_hash_algorithm then 145.11 config.password_hash_algorithm = "crypt_sha512" 145.12 @@ -18,7 +18,7 @@ 145.13 end 145.14 145.15 if config.enabled_languages == nil then 145.16 - config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-Hans', 'zh-TW' } 145.17 + config.enabled_languages = { 'en', 'de' } --, 'eo', 'el', 'hu', 'it', 'nl', 'zh-Hans', 'zh-TW' } 145.18 end 145.19 145.20 if config.default_lang == nil then
146.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 146.2 +++ b/config/lf3.lua Thu Jul 10 01:19:48 2014 +0200 146.3 @@ -0,0 +1,290 @@ 146.4 +-- ======================================================================== 146.5 +-- MANDATORY (MUST BE CAREFULLY CHECKED AND PROPERLY SET!) 146.6 +-- ======================================================================== 146.7 + 146.8 +-- Name of this instance, defaults to name of config file 146.9 +-- ------------------------------------------------------------------------ 146.10 +config.instance_name = "Public Software Group e.V." 146.11 + 146.12 + 146.13 +-- Information about service provider (HTML) 146.14 +-- ------------------------------------------------------------------------ 146.15 +config.app_service_provider = [[ 146.16 +Public Software Group e. V.<br /> 146.17 +Johannisstr. 12<br /> 146.18 +10117 Berlin<br /> 146.19 +Germany<br /><br /> 146.20 +eingetragen im Vereinsregister des Amtsgerichtes Charlottenburg unter der 146.21 + Registernummer VR 28873 B<br /> 146.22 +vertreten durch die Vorstandsmitglieder Jan Behrens, Axel Kistner, Andreas 146.23 + Nitsche und Björn Swierczek jeweils mit Einzelvertretungsbefugnis 146.24 +]] 146.25 + 146.26 + 146.27 +-- A HTML formatted text the user has to accept while registering 146.28 +-- ------------------------------------------------------------------------ 146.29 +config.use_terms = [[ 146.30 +<h1>Terms of Use</h1> 146.31 +<p> 146.32 + All data display below and all data you enter later while using the system 146.33 + and all data you are submitting via the programming interface will be 146.34 + stored in the LiquidFeedback database and published. Every access to the 146.35 + system is subject of tracing and logging for development purposes. 146.36 +</p> 146.37 +<p> 146.38 + Please notice, this is a **public test dedicated to developers**: serious 146.39 + errors can happen or private data unintentionally published. 146.40 +</p> 146.41 +<p> 146.42 + Everything is <b>ON YOUR OWN RISK</b> 146.43 +</p> 146.44 +]] 146.45 + 146.46 +-- Checkbox(es) the user has to accept while registering 146.47 +-- ------------------------------------------------------------------------ 146.48 +config.use_terms_checkboxes = { 146.49 + { 146.50 + name = "terms_of_use_20140514", 146.51 + html = "I accept the terms of use.", 146.52 + not_accepted_error = "You have to accept the terms of use to be able to register." 146.53 + }, 146.54 +-- { 146.55 +-- name = "extra_terms_of_use_v1", 146.56 +-- html = "I accept the extra terms of use.", 146.57 +-- not_accepted_error = "You have to accept the extra terms of use to be able to register." 146.58 +-- } 146.59 +} 146.60 + 146.61 + 146.62 +-- Absolute base url of application 146.63 +-- ------------------------------------------------------------------------ 146.64 +config.absolute_base_url = "http://dev.liquidfeedback.org/lf3/" 146.65 + 146.66 + 146.67 +-- Connection information for the LiquidFeedback database 146.68 +-- ------------------------------------------------------------------------ 146.69 +config.database = { engine='postgresql', dbname='lf3' } 146.70 + 146.71 + 146.72 +-- Location of the rocketwiki binaries 146.73 +-- ------------------------------------------------------------------------ 146.74 +config.enforce_formatting_engine = "markdown2" 146.75 + 146.76 +config.formatting_engines = { 146.77 + { id = "markdown_py", 146.78 + name = "Python Markdown", 146.79 + executable = "markdown_py", 146.80 + args = {'/dev/stdin', '-s', 'escape', '-x', 'extra', '-x', 'nl2br', '-x', 'sane_lists'}, 146.81 + remove_images = true 146.82 + }, 146.83 + { id = "markdown2", 146.84 + name = "markdown2", 146.85 + executable = "markdown2", 146.86 + args = {'-s', 'escape', '-x', 'cuddled-lists,nofollow,wiki-tables'}, 146.87 + remove_images = true 146.88 + }, 146.89 + { id = "multimarkdown", 146.90 + name = "MultiMarkdown", 146.91 + executable = "multimarkdown", 146.92 + args = {'--filter-html', '--filter-styles', '--nolabels' ,'-x'} 146.93 + }, 146.94 + { id = "rocketwiki", 146.95 + name = "RocketWiki", 146.96 + executable = "/opt/liquid_feedback3/rocketwiki-lqfb/rocketwiki-lqfb", 146.97 + remove_images = false 146.98 + }, 146.99 + { id = "compat", 146.100 + name = "Traditional WIKI syntax", 146.101 + executable = "/opt/liquid_feedback3/rocketwiki-lqfb/rocketwiki-lqfb-compat", 146.102 + remove_images = false 146.103 + } 146.104 +} 146.105 + 146.106 +-- Public access level 146.107 +-- ------------------------------------------------------------------------ 146.108 +-- Available options: 146.109 +-- "none" 146.110 +-- -> Closed user group, no public access at all 146.111 +-- (except login/registration/password reset) 146.112 +-- "anonymous" 146.113 +-- -> Shows only initiative/suggestions texts and aggregated 146.114 +-- supporter/voter counts 146.115 +-- "authors_pseudonymous" 146.116 +-- -> Like anonymous, but shows screen names of authors 146.117 +-- "all_pseudonymous" 146.118 +-- -> Show everything a member can see, except profile pages 146.119 +-- "everything" 146.120 +-- -> Show everything a member can see, including profile pages 146.121 +-- ------------------------------------------------------------------------ 146.122 +config.public_access = "none" 146.123 + 146.124 + 146.125 + 146.126 +-- ======================================================================== 146.127 +-- OPTIONAL 146.128 +-- Remove leading -- to use a option 146.129 +-- ======================================================================== 146.130 + 146.131 +-- List of enabled languages, defaults to available languages 146.132 +-- ------------------------------------------------------------------------ 146.133 +-- config.enabled_languages = { 'en', 'de', 'eo', 'el', 'hu', 'it', 'nl', 'zh-TW' } 146.134 +config.enabled_languages = { 'en', 'de' } 146.135 + 146.136 +-- Default language, defaults to "en" 146.137 +-- ------------------------------------------------------------------------ 146.138 +-- config.default_lang = "de" 146.139 + 146.140 +-- after how long is a user considered inactive and the trustee will see warning, 146.141 +-- notation is according to postgresql intervals, default: no warning at all 146.142 +-- ------------------------------------------------------------------------ 146.143 +config.delegation_warning_time = '3 month' 146.144 + 146.145 +-- after which time a user is suggested to (_soft) or forced to (_hard) 146.146 +-- confirm unit and area delegations. default: no confirmation at all 146.147 +-- ------------------------------------------------------------------------ 146.148 +-- config.check_delegations_interval_hard = "1 day" 146.149 +-- config.check_delegations_interval_soft = "3 seconds" 146.150 + 146.151 +-- default options should be checked when confirming delegations 146.152 +-- options: "confirm", "revoke" and "none" 146.153 +-- ------------------------------------------------------------------------ 146.154 +-- config.check_delegations_default = "confirm" 146.155 + 146.156 +-- Prefix of all automatic mails, defaults to "[Liquid Feedback] " 146.157 +-- ------------------------------------------------------------------------ 146.158 +config.mail_subject_prefix = "[LiquidFeedback 3.0 Test] " 146.159 + 146.160 +-- Sender of all automatic mails, defaults to system defaults 146.161 +-- ------------------------------------------------------------------------ 146.162 +config.mail_envelope_from = "lqfb-maintainers@public-software-group.org" 146.163 +config.mail_from = { name = "LiquidFeedback", address = "lqfb-maintainers@public-software-group.org" } 146.164 +--config.mail_reply_to = { name = "Support", address = "support@example.com" } 146.165 + 146.166 +-- Configuration of password hashing algorithm (defaults to "crypt_sha512") 146.167 +-- ------------------------------------------------------------------------ 146.168 +-- config.password_hash_algorithm = "crypt_sha512" 146.169 +-- config.password_hash_algorithm = "crypt_sha256" 146.170 +-- config.password_hash_algorithm = "crypt_md5" 146.171 + 146.172 +-- Number of rounds for crypt_sha* algorithms, minimum and maximum 146.173 +-- (defaults to minimum 10000 and maximum 20000) 146.174 +-- ------------------------------------------------------------------------ 146.175 +-- config.password_hash_min_rounds = 10000 146.176 +-- config.password_hash_max_rounds = 20000 146.177 + 146.178 +-- Supply custom url for avatar/photo delivery 146.179 +-- ------------------------------------------------------------------------ 146.180 +-- config.fastpath_url_func = nil 146.181 + 146.182 +-- Local directory for database dumps offered for download 146.183 +-- ------------------------------------------------------------------------ 146.184 +-- config.download_dir = nil 146.185 + 146.186 +-- Special use terms for database dump download 146.187 +-- ------------------------------------------------------------------------ 146.188 +-- config.download_use_terms = "=== Download use terms ===\n" 146.189 + 146.190 +-- Use custom image conversion, defaults to ImageMagick's convert 146.191 +-- ------------------------------------------------------------------------ 146.192 +--config.member_image_content_type = "image/jpeg" 146.193 +--config.member_image_convert_func = { 146.194 +-- avatar = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "48x48", "jpeg:-") end, 146.195 +-- photo = function(data) return extos.pfilter(data, "convert", "jpeg:-", "-thumbnail", "240x240", "jpeg:-") end 146.196 +--} 146.197 + 146.198 +-- Display a html formatted public message of the day 146.199 +-- ------------------------------------------------------------------------ 146.200 +-- config.motd_public = "<h1>Message of the day (public)</h1><p>The MOTD is formatted with HTML</p>" 146.201 + 146.202 +-- Display a html formatted internal message of the day 146.203 +-- ------------------------------------------------------------------------ 146.204 +-- config.motd_public = "<h1>Message of the day (intern)</h1><p>The MOTD is formatted with HTML</p>" 146.205 + 146.206 +-- Automatic issue related discussion URL 146.207 +-- ------------------------------------------------------------------------ 146.208 +-- config.issue_discussion_url_func = function(issue) 146.209 +-- return "http://example.com/discussion/issue_" .. tostring(issue.id) 146.210 +-- end 146.211 + 146.212 +-- Configuration of "tell others" 146.213 +-- ------------------------------------------------------------------------ 146.214 +config.tell_others = { 146.215 + initiative = function (initiative) 146.216 + local text = "i" .. initiative.id .. ": " .. initiative.name .. " " .. request.get_absolute_baseurl() .. "initiative/" .. initiative.id .. ".html" 146.217 + return { 146.218 + { content = "Tweet this initiative", external = "https://twitter.com/intent/tweet?text=" .. encode.url_part(text) }, 146.219 + { content = "Send an eMail", external = "mailto:?subject=" .. encode.url_part(initiative.display_name) .. "&body=" .. encode.url_part(text) } 146.220 + } 146.221 + end 146.222 +} 146.223 + 146.224 +-- Integration of Etherpad, disabled by default 146.225 +-- ------------------------------------------------------------------------ 146.226 +--config.etherpad = { 146.227 +-- base_url = "http://example.com:9001/", 146.228 +-- api_base = "http://localhost:9001/", 146.229 +-- api_key = "mysecretapikey", 146.230 +-- group_id = "mygroupname", 146.231 +-- cookie_path = "/" 146.232 +--} 146.233 + 146.234 +-- Free timings, may be used together with polling policies 146.235 +-- ------------------------------------------------------------------------ 146.236 +-- This example expects a date string entered in the free timing field 146.237 +-- by the user creating a poll, interpreting it as target date for then 146.238 +-- poll and splits the remainig time at the ratio of 4:1:2 146.239 +-- Please note, polling policies never have an admission phase 146.240 + 146.241 + 146.242 +config.free_timing = { 146.243 + calculate_func = function(policy, timing_string) 146.244 + function interval_by_seconds(secs) 146.245 + local secs_per_day = 60 * 60 * 24 146.246 + local days 146.247 + days = math.floor(secs / secs_per_day) 146.248 + secs = secs - days * secs_per_day 146.249 + return days .. " days " .. secs .. " seconds" 146.250 + end 146.251 + local target_date = parse.date(timing_string, atom.date) 146.252 + if not target_date then 146.253 + return false 146.254 + end 146.255 + local target_timestamp = target_date.midday 146.256 + local now = atom.timestamp:get_current() 146.257 + trace.debug(target_timestamp, now) 146.258 + local duration = target_timestamp - now 146.259 + if duration < 0 then 146.260 + return false 146.261 + end 146.262 + return { 146.263 + discussion = interval_by_seconds(duration / 7 * 4), 146.264 + verification = interval_by_seconds(duration / 7 * 1), 146.265 + voting = interval_by_seconds(duration / 7 * 2) 146.266 + } 146.267 + end, 146.268 + available_func = function(policy) 146.269 + return { 146.270 + { name = "End of 2014", id = '2014-12-31' }, 146.271 + { name = "End of 2015", id = '2015-12-31' }, 146.272 + { name = "End of 2016", id = '2016-12-31' } 146.273 + } 146.274 + end 146.275 +} 146.276 + 146.277 + 146.278 +config.enable_debug_trace = true 146.279 + 146.280 +-- WebMCP accelerator 146.281 +-- uncomment the following two lines to use C implementations of chosen 146.282 +-- functions and to disable garbage collection during the request, to 146.283 +-- increase speed: 146.284 +-- ------------------------------------------------------------------------ 146.285 +-- require 'webmcp_accelerator' 146.286 +-- if cgi then collectgarbage("stop") end 146.287 + 146.288 + 146.289 +-- ======================================================================== 146.290 +-- Do main initialisation (DO NOT REMOVE FOLLOWING SECTION) 146.291 +-- ======================================================================== 146.292 + 146.293 +execute.config("init")
147.1 --- a/env/format/interval_text.lua Thu Jul 10 01:02:43 2014 +0200 147.2 +++ b/env/format/interval_text.lua Thu Jul 10 01:19:48 2014 +0200 147.3 @@ -7,7 +7,7 @@ 147.4 :gsub("day", "{DAY}") 147.5 :gsub("mons", "{MONS}") 147.6 :gsub("mon", "{MON}") 147.7 - :gsub("yeas", "{YEARS}") 147.8 + :gsub("years", "{YEARS}") 147.9 :gsub("year", "{YEAR}") 147.10 147.11 if (options.mode == "time_left") then 147.12 @@ -42,4 +42,4 @@ 147.13 return _("#{interval_text} [interval]", { interval_text = interval_text }) 147.14 147.15 end 147.16 -end 147.17 \ No newline at end of file 147.18 +end
148.1 --- a/env/format/wiki_text.lua Thu Jul 10 01:02:43 2014 +0200 148.2 +++ b/env/format/wiki_text.lua Thu Jul 10 01:19:48 2014 +0200 148.3 @@ -1,12 +1,38 @@ 148.4 function format.wiki_text(wiki_text, formatting_engine) 148.5 - local formatting_engine = formatting_engine or "rocketwiki" 148.6 + 148.7 + if not formatting_engine then 148.8 + error("Formatting engine identifier required") 148.9 + end 148.10 + 148.11 + local fe 148.12 + 148.13 + for i, fe_entry in ipairs(config.formatting_engines) do 148.14 + if fe_entry.id == formatting_engine then 148.15 + fe = fe_entry 148.16 + break 148.17 + end 148.18 + end 148.19 + 148.20 + if not fe then 148.21 + error("Formatting engine not found") 148.22 + end 148.23 + 148.24 local html, errmsg, exitcode = assert( 148.25 - extos.pfilter(wiki_text, config.formatting_engine_executeables[formatting_engine]) 148.26 + extos.pfilter(wiki_text, fe.executable, table.unpack(fe.args or {})) 148.27 ) 148.28 + 148.29 if exitcode > 0 then 148.30 + trace.debug(html, errmsg) 148.31 error("Wiki parser process returned with error code " .. tostring(exitcode)) 148.32 elseif exitcode < 0 then 148.33 + trace.debug(html, errmsg) 148.34 error("Wiki parser process was terminated by signal " .. tostring(-exitcode)) 148.35 end 148.36 + 148.37 + if fe.remove_images then 148.38 + html = string.gsub(html, '<img [^>]*>', '') 148.39 + end 148.40 + 148.41 return html 148.42 + 148.43 end
149.1 --- a/env/model/has_rendered_content.lua Thu Jul 10 01:02:43 2014 +0200 149.2 +++ b/env/model/has_rendered_content.lua Thu Jul 10 01:19:48 2014 +0200 149.3 @@ -47,7 +47,11 @@ 149.4 rendered[class.table .. "_id"] = self.id 149.5 end 149.6 rendered.format = "html" 149.7 - rendered.content = format.wiki_text(self[content_field_name], self.formatting_engine) 149.8 + if self.formatting_engine then 149.9 + rendered.content = format.wiki_text(self[content_field_name], self.formatting_engine) 149.10 + else 149.11 + rendered.content = self[content_field_name] 149.12 + end 149.13 rendered:save() 149.14 -- and return it 149.15 return rendered
150.1 --- a/env/ui/actions.lua Thu Jul 10 01:02:43 2014 +0200 150.2 +++ b/env/ui/actions.lua Thu Jul 10 01:19:48 2014 +0200 150.3 @@ -1,5 +1,5 @@ 150.4 function ui.actions(content) 150.5 - slot.select("head", function() 150.6 + slot.select("actions", function() 150.7 ui.container{ attr = { class = "actions" }, content = content } 150.8 end) 150.9 end 150.10 \ No newline at end of file
151.1 --- a/env/ui/bargraph.lua Thu Jul 10 01:02:43 2014 +0200 151.2 +++ b/env/ui/bargraph.lua Thu Jul 10 01:19:48 2014 +0200 151.3 @@ -35,7 +35,7 @@ 151.4 attr = { 151.5 style = "width: " .. tostring(dlength_abs) .. "px; background-color: " .. bar.color .. ";", 151.6 }, 151.7 - content = function() slot.put(" ") end 151.8 + content = "" 151.9 } 151.10 end 151.11 ui.container{ 151.12 @@ -43,7 +43,7 @@ 151.13 class = "quorum", 151.14 style = "width: 1px; background-color: " .. (args.quorum_color or "blue") ..";", 151.15 }, 151.16 - content = function() slot.put("") end 151.17 + content = "" 151.18 } 151.19 length = dlength + 1 151.20 value = value - dlength 151.21 @@ -59,7 +59,7 @@ 151.22 attr = { 151.23 style = "width: " .. tostring(value_abs) .. "px; background-color: " .. bar.color .. ";", 151.24 }, 151.25 - content = function() slot.put(" ") end 151.26 + content = "" 151.27 } 151.28 end 151.29 end
152.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 152.2 +++ b/env/ui/contextbar.lua Thu Jul 10 01:19:48 2014 +0200 152.3 @@ -0,0 +1,17 @@ 152.4 +function ui.contextbar ( arg1, arg2 ) 152.5 + 152.6 + local class = "sidebarSection" 152.7 + local content 152.8 + 152.9 + if arg2 then 152.10 + class = class .. " " .. arg1 152.11 + content = arg2 152.12 + else 152.13 + content = arg1 152.14 + end 152.15 + 152.16 + slot.select ( "contextbar", function () 152.17 + ui.container { attr = { class = class }, content = content } 152.18 + end ) 152.19 + 152.20 +end
153.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 153.2 +++ b/env/ui/delegation.lua Thu Jul 10 01:19:48 2014 +0200 153.3 @@ -0,0 +1,19 @@ 153.4 +function ui.delegation(to_member_id, to_member_name) 153.5 + local text = _"delegates to" 153.6 + ui.image{ 153.7 + attr = { class = "delegation_arrow", alt = text, title = text }, 153.8 + static = "delegation_arrow_24_horizontal.png" 153.9 + } 153.10 + 153.11 + if to_member_id and to_member_name then 153.12 + execute.view{ 153.13 + module = "member_image", view = "_show", params = { 153.14 + member_id = to_member_id, 153.15 + class = "micro_avatar", 153.16 + image_type = "avatar", 153.17 + popup_text = to_member_name, 153.18 + show_dummy = true 153.19 + } 153.20 + } 153.21 + end 153.22 +end 153.23 \ No newline at end of file
154.1 --- a/env/ui/filters.lua Thu Jul 10 01:02:43 2014 +0200 154.2 +++ b/env/ui/filters.lua Thu Jul 10 01:19:48 2014 +0200 154.3 @@ -20,8 +20,12 @@ 154.4 end 154.5 local id = param.get_id_cgi() 154.6 local params = param.get_all_cgi() 154.7 + local class = "ui_filter_head" 154.8 + if filter.class then 154.9 + class = class .. " " .. filter.class 154.10 + end 154.11 ui.container{ 154.12 - attr = { class = "ui_filter_head" }, 154.13 + attr = { class = class }, 154.14 content = function() 154.15 slot.put(filter.label) 154.16 for idx, option in ipairs(filter) do
155.1 --- a/env/ui/raw_title.lua Thu Jul 10 01:02:43 2014 +0200 155.2 +++ b/env/ui/raw_title.lua Thu Jul 10 01:19:48 2014 +0200 155.3 @@ -1,7 +1,20 @@ 155.4 -function ui.raw_title(content) 155.5 - slot.select("head", function() 155.6 - ui.container{ attr = { class = "title" }, content = function() 155.7 - slot.put(content) 155.8 - end } 155.9 - end) 155.10 -end 155.11 \ No newline at end of file 155.12 +function ui.raw_title ( content ) 155.13 + 155.14 + slot.select ( "title", function () 155.15 + 155.16 + -- home link 155.17 + ui.link { 155.18 + module = "index", view = "index", 155.19 + attr = { class = "home" }, 155.20 + content = function () 155.21 + ui.image { static = "icons/16/house.png" } 155.22 + end 155.23 + } 155.24 + 155.25 + slot.put ( " " ) 155.26 + 155.27 + slot.put ( content ) 155.28 + 155.29 + end ) 155.30 + 155.31 +end
156.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 156.2 +++ b/env/ui/section.lua Thu Jul 10 01:19:48 2014 +0200 156.3 @@ -0,0 +1,15 @@ 156.4 +function ui.section ( arg1, arg2 ) 156.5 + 156.6 + local class = "section" 156.7 + local content 156.8 + 156.9 + if arg2 then 156.10 + class = class .. " " .. arg1 156.11 + content = arg2 156.12 + else 156.13 + content = arg1 156.14 + end 156.15 + 156.16 + ui.container { attr = { class = class }, content = content } 156.17 + 156.18 +end
157.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 157.2 +++ b/env/ui/sectionHead.lua Thu Jul 10 01:19:48 2014 +0200 157.3 @@ -0,0 +1,15 @@ 157.4 +function ui.sectionHead ( arg1, arg2 ) 157.5 + 157.6 + local class = "sectionHead" 157.7 + local content 157.8 + 157.9 + if arg2 then 157.10 + class = class .. " " .. arg1 157.11 + content = arg2 157.12 + else 157.13 + content = arg1 157.14 + end 157.15 + 157.16 + ui.container { attr = { class = class }, content = content } 157.17 + 157.18 +end
158.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 158.2 +++ b/env/ui/sectionRow.lua Thu Jul 10 01:19:48 2014 +0200 158.3 @@ -0,0 +1,15 @@ 158.4 +function ui.sectionRow ( arg1, arg2 ) 158.5 + 158.6 + local class = "sectionRow" 158.7 + local content 158.8 + 158.9 + if arg2 then 158.10 + class = class .. " " .. arg1 158.11 + content = arg2 158.12 + else 158.13 + content = arg1 158.14 + end 158.15 + 158.16 + ui.container { attr = { class = class }, content = content } 158.17 + 158.18 +end
159.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 159.2 +++ b/env/ui/sidebar.lua Thu Jul 10 01:19:48 2014 +0200 159.3 @@ -0,0 +1,17 @@ 159.4 +function ui.sidebar ( arg1, arg2 ) 159.5 + 159.6 + local class = "sidebarSection" 159.7 + local content 159.8 + 159.9 + if arg2 then 159.10 + class = class .. " " .. arg1 159.11 + content = arg2 159.12 + else 159.13 + content = arg1 159.14 + end 159.15 + 159.16 + slot.select ( "sidebar", function () 159.17 + ui.container { attr = { class = class }, content = content } 159.18 + end ) 159.19 + 159.20 +end
160.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 160.2 +++ b/env/ui/sidebarHead.lua Thu Jul 10 01:19:48 2014 +0200 160.3 @@ -0,0 +1,15 @@ 160.4 +function ui.sidebarHead ( arg1, arg2 ) 160.5 + 160.6 + local class = "sidebarHead" 160.7 + local content 160.8 + 160.9 + if arg2 then 160.10 + class = class .. " " .. arg1 160.11 + content = arg2 160.12 + else 160.13 + content = arg1 160.14 + end 160.15 + 160.16 + ui.container { attr = { class = class }, content = content } 160.17 + 160.18 +end
161.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 161.2 +++ b/env/ui/sidebarHeadWhatCanIDo.lua Thu Jul 10 01:19:48 2014 +0200 161.3 @@ -0,0 +1,21 @@ 161.4 +function ui.sidebarHeadWhatCanIDo () 161.5 + ui.sidebarHead( function () 161.6 + --ui.image{ attr = { class = "right icon24" }, static = "icons/48/info.png" } 161.7 + ui.heading { 161.8 + level = 2, content = _"What can I do here?" 161.9 + } 161.10 + end ) 161.11 + if not app.session.member then 161.12 + ui.sidebarSection( function() 161.13 + ui.heading { level = 3, content = _"Closed user group" } 161.14 + ui.tag { tag = "ul", attr = { class = "ul" }, content = function () 161.15 + ui.tag { tag = "li", content = function () 161.16 + ui.link { 161.17 + content = _"login to participate", 161.18 + module = "index", view = "login" 161.19 + } 161.20 + end } 161.21 + end } 161.22 + end ) 161.23 + end 161.24 +end
162.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 162.2 +++ b/env/ui/sidebarSection.lua Thu Jul 10 01:19:48 2014 +0200 162.3 @@ -0,0 +1,15 @@ 162.4 +function ui.sidebarSection ( arg1, arg2 ) 162.5 + 162.6 + local class = "sidebarRow" 162.7 + local content 162.8 + 162.9 + if arg2 then 162.10 + class = class .. " " .. arg1 162.11 + content = arg2 162.12 + else 162.13 + content = arg1 162.14 + end 162.15 + 162.16 + ui.container { attr = { class = class }, content = content } 162.17 + 162.18 +end
163.1 --- a/env/ui/title.lua Thu Jul 10 01:02:43 2014 +0200 163.2 +++ b/env/ui/title.lua Thu Jul 10 01:19:48 2014 +0200 163.3 @@ -1,5 +1,31 @@ 163.4 -function ui.title(content) 163.5 - slot.select("head", function() 163.6 - ui.container{ attr = { class = "title" }, content = content } 163.7 - end) 163.8 -end 163.9 \ No newline at end of file 163.10 +function ui.title ( content ) 163.11 + 163.12 + slot.select ( "title", function () 163.13 + 163.14 + -- home link 163.15 + ui.link { 163.16 + module = "index", view = "index", 163.17 + attr = { class = "home", title = _"Home" }, 163.18 + content = function () 163.19 + ui.image { 163.20 + attr = { class = "icon24", alt = title }, 163.21 + static = "icons/48/home.png" 163.22 + } 163.23 + end 163.24 + } 163.25 + 163.26 + if content then 163.27 + ui.tag { attr = { class = "spacer" }, content = function() 163.28 + slot.put ( " » " ) 163.29 + end } 163.30 + ui.tag { tag = "span", content = content } 163.31 + else 163.32 + ui.tag { attr = { class = "spacer" }, content = function() 163.33 + slot.put ( " " ) 163.34 + end } 163.35 + ui.tag { tag = "span", content = _"Home" } 163.36 + end 163.37 + 163.38 + end ) 163.39 + 163.40 +end
164.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 164.2 +++ b/env/ui/titleAdmin.lua Thu Jul 10 01:19:48 2014 +0200 164.3 @@ -0,0 +1,8 @@ 164.4 +function ui.titleAdmin(title) 164.5 + ui.title(function() 164.6 + ui.link { module = "admin", view = "index", content = _"System administration" } 164.7 + if title then 164.8 + ui.tag { tag = "span", content = content } 164.9 + end 164.10 + end) 164.11 +end 164.12 \ No newline at end of file
165.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 165.2 +++ b/env/ui/titleMember.lua Thu Jul 10 01:19:48 2014 +0200 165.3 @@ -0,0 +1,17 @@ 165.4 +function ui.titleMember(title, title2) 165.5 + local member = app.session.member 165.6 + if type(title) == "table" then 165.7 + member = title 165.8 + title = title2 165.9 + end 165.10 + ui.title(function() 165.11 + if member then 165.12 + ui.link { module = "member", view = "show", id = member.id, content = member.name } 165.13 + end 165.14 + if title then 165.15 + ui.tag { attr = { class = "member" }, content = function() 165.16 + ui.tag{ tag = "span", content = title } 165.17 + end } 165.18 + end 165.19 + end) 165.20 +end 165.21 \ No newline at end of file
166.1 --- a/env/util/help.lua Thu Jul 10 01:02:43 2014 +0200 166.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 166.3 @@ -1,68 +0,0 @@ 166.4 -function util.help(id, title) 166.5 - if not app.session.member_id then 166.6 - return 166.7 - end 166.8 - local setting_key = "liquidfeedback_frontend_hidden_help_" .. id 166.9 - local setting = Setting:by_pk(app.session.member.id, setting_key) 166.10 - if not setting then 166.11 - ui.container{ 166.12 - attr = { class = "help help_visible" }, 166.13 - content = function() 166.14 - ui.image{ 166.15 - attr = { class = "help_icon" }, 166.16 - static = "icons/16/help.png" 166.17 - } 166.18 - ui.container{ 166.19 - attr = { class = "help_actions" }, 166.20 - content = function() 166.21 - ui.link{ 166.22 - text = _"Hide this help message", 166.23 - module = "help", 166.24 - action = "update", 166.25 - params = { 166.26 - help_ident = id, 166.27 - hide = true 166.28 - }, 166.29 - routing = { 166.30 - default = { 166.31 - mode = "redirect", 166.32 - module = request.get_module(), 166.33 - view = request.get_view(), 166.34 - id = param.get_id_cgi(), 166.35 - params = param.get_all_cgi() 166.36 - } 166.37 - } 166.38 - } 166.39 - end 166.40 - } 166.41 - local lang = locale.get("lang") 166.42 - local basepath = request.get_app_basepath() 166.43 - local file_name = basepath .. "/locale/help/" .. id .. "." .. lang .. ".txt.html" 166.44 - local file = io.open(file_name) 166.45 - if file ~= nil then 166.46 - local help_text = file:read("*a") 166.47 - if #help_text > 0 then 166.48 - ui.container{ 166.49 - attr = { class = "wiki" }, 166.50 - content = function() 166.51 - slot.put(help_text) 166.52 - end 166.53 - } 166.54 - else 166.55 - ui.field.text{ value = _("Empty help text: #{id}.#{lang}.txt", { id = id, lang = lang }) } 166.56 - end 166.57 - else 166.58 - ui.field.text{ value = _("Missing help text: #{id}.#{lang}.txt", { id = id, lang = lang }) } 166.59 - end 166.60 - end 166.61 - } 166.62 - else 166.63 - if util._hidden_helps == nil then 166.64 - util._hidden_helps = {} 166.65 - end 166.66 - util._hidden_helps[#util._hidden_helps+1] = { 166.67 - id = id, 166.68 - title = title 166.69 - } 166.70 - end 166.71 -end 166.72 \ No newline at end of file
167.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 167.2 +++ b/env/util/initiative_pie.lua Thu Jul 10 01:19:48 2014 +0200 167.3 @@ -0,0 +1,137 @@ 167.4 +function util.initiative_pie(initiative, d, gap) 167.5 + if not initiative.issue.closed or not initiative.admitted then 167.6 + return 167.7 + end 167.8 + 167.9 + if initiative.issue.voter_count == 0 or initiative.positive_votes == nil or initiative.negative_votes == nil then 167.10 + return 167.11 + end 167.12 + 167.13 + local first_preference_votes = initiative.first_preference_votes 167.14 + if first_preference_votes == nil then 167.15 + first_preference_votes = 0 167.16 + end 167.17 + 167.18 + local d = d or 100 167.19 + local gap = gap or d / 20 167.20 + 167.21 + local r = d/2 167.22 + local r_circle = r - gap 167.23 + 167.24 + local function circle(p) 167.25 + return 167.26 + gap + 2 * r_circle * ( 1 + math.sin( 2 * math.pi * p ) ) / 2, 167.27 + gap + 2 * r_circle * ( 1 - math.cos( 2 * math.pi * p ) ) / 2 167.28 + end 167.29 + 167.30 + local function getpath(start, stop) 167.31 + local start_x, start_y = circle(start) 167.32 + local stop_x, stop_y = circle(stop) 167.33 + local large = stop - start > 0.5 and "1" or "0" 167.34 + return "M" .. r .. "," .. r .. " " 167.35 + .. "L" .. start_x .. ",".. start_y .. " " .. " " 167.36 + .. "A" .. r_circle .. "," .. r_circle .. " 0 " .. large .. ",1 " .. stop_x .. "," .. stop_y .. " " 167.37 + .. "z" 167.38 + end 167.39 + 167.40 + local function uniPie(color, content) 167.41 + ui.tag { 167.42 + tag = "svg", 167.43 + attr = { 167.44 + class = "initiative_pie", 167.45 + width = d .. "px", 167.46 + height = d .. "px", 167.47 + }, 167.48 + content = function () 167.49 + ui.tag { tag = "circle", attr = { 167.50 + cx=r, cy=r, r=r_circle, fill = color, stroke = "#fff", ["stroke-width"] = "2" 167.51 + }, content = function () ui.tag { tag = "title", content = content } end } 167.52 + end 167.53 + } 167.54 + end 167.55 + 167.56 + local function piePiece(path, fill, content) 167.57 + ui.tag { 167.58 + tag = "path", 167.59 + attr = { 167.60 + d = path, 167.61 + fill = fill, 167.62 + stroke = "#fff", 167.63 + ["stroke-width"] = "2", 167.64 + ["stroke-linecap"] = "butt" 167.65 + }, 167.66 + content = function () 167.67 + ui.tag { 167.68 + tag = "title", 167.69 + content = content 167.70 + } 167.71 + end 167.72 + } 167.73 + end 167.74 + 167.75 + local function pie(args) 167.76 + local offset = args.offset or 0 167.77 + local list = {} 167.78 + local sum = 0 167.79 + for i, element in ipairs(args) do 167.80 + element.start = sum + offset 167.81 + list[#list+1] = element 167.82 + sum = sum + element.value 167.83 + end 167.84 + 167.85 + for i, element in ipairs(list) do 167.86 + if element.value == sum then 167.87 + uniPie(element.fill, _(element.label, { count = element.value } )) 167.88 + return 167.89 + end 167.90 + end 167.91 + ui.tag { 167.92 + tag = "svg", 167.93 + attr = { 167.94 + class = "initiative_pie", 167.95 + width = d .. "px", 167.96 + height = d .. "px" 167.97 + }, 167.98 + content = function () 167.99 + table.sort(list, function (a, b) 167.100 + return a.value < b.value 167.101 + end ) 167.102 + for i, element in ipairs(list) do 167.103 + local path = getpath(element.start / sum, (element.start + element.value) / sum) 167.104 + local content = _(element.label, { count = element.value }) 167.105 + piePiece(path, element.fill, content) 167.106 + end 167.107 + end 167.108 + } 167.109 + end 167.110 + 167.111 + local yes1 = first_preference_votes 167.112 + local yes = initiative.positive_votes - first_preference_votes 167.113 + local neutral = initiative.issue.voter_count - initiative.positive_votes - initiative.negative_votes 167.114 + local no = initiative.negative_votes 167.115 + 167.116 + local sum = yes1 + yes + neutral + no 167.117 + 167.118 + local q = initiative.issue.policy.direct_majority_num / initiative.issue.policy.direct_majority_den 167.119 + 167.120 + 167.121 + local maxrot = sum * 7 / 12 - no 167.122 + 167.123 + local offset = 0 167.124 + 167.125 + if maxrot > 0 then 167.126 + offset = math.min ( 167.127 + maxrot, 167.128 + no * ( 1 / ( 1 / q - 1 ) -1 ) / 2 167.129 + ) 167.130 + end 167.131 + 167.132 + pie{ 167.133 + { value = yes1, fill = "#0a0", label = _"#{count} Yes, first choice" }, 167.134 + { value = yes, fill = "#6c6", label = _"#{count} Yes, alternative choice" }, 167.135 + { value = neutral, fill = "#ccc", label = _"#{count} Neutral" }, 167.136 + { value = no, fill = "#c00", label = _"#{count} No" }, 167.137 + offset = - offset 167.138 + } 167.139 + 167.140 +end 167.141 \ No newline at end of file
168.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 168.2 +++ b/env/util/micro_avatar.lua Thu Jul 10 01:19:48 2014 +0200 168.3 @@ -0,0 +1,49 @@ 168.4 +function util.micro_avatar(member, member_name) 168.5 + if type ( member ) == "number" then 168.6 + member = { 168.7 + id = member, 168.8 + name = member_name 168.9 + } 168.10 + end 168.11 + 168.12 + function doit() 168.13 + if config.fastpath_url_func then 168.14 + ui.image{ 168.15 + attr = { 168.16 + title = member.name, 168.17 + class = "microAvatar" 168.18 + }, 168.19 + external = config.fastpath_url_func(member.id, "avatar") 168.20 + } 168.21 + else 168.22 + ui.image { 168.23 + attr = { 168.24 + title = member.name, 168.25 + class = "microAvatar" 168.26 + }, 168.27 + module = "member_image", 168.28 + view = "show", 168.29 + extension = "jpg", 168.30 + id = member.id, 168.31 + params = { 168.32 + image_type = "avatar" 168.33 + } 168.34 + } 168.35 + end 168.36 + ui.tag { tag = "span", content = member.name } 168.37 + end 168.38 + 168.39 + ui.tag { 168.40 + attr = { class = "microAvatar" }, 168.41 + content = function () 168.42 + if app.session:has_access("everything") then 168.43 + ui.link { 168.44 + module = "member", view = "show", id = member.id, 168.45 + content = doit 168.46 + } 168.47 + else 168.48 + ui.tag{ content = doit } 168.49 + end 168.50 + end 168.51 + } 168.52 +end
169.1 --- a/locale/Makefile Thu Jul 10 01:02:43 2014 +0200 169.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 169.3 @@ -1,18 +0,0 @@ 169.4 -PATH:=$(PATH):/opt/rocketwiki/ 169.5 - 169.6 -DIRS = help 169.7 -HTML_SOURCE := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.txt)) 169.8 -HTML_HELP := $(HTML_SOURCE:.txt=.txt.html) 169.9 -TARGET = all 169.10 - 169.11 - 169.12 -%.txt.html: %.txt 169.13 - rocketwiki-lqfb < $< > $@ 169.14 - 169.15 - 169.16 -help_html: $(HTML_HELP) 169.17 - 169.18 -clean: 169.19 - rm -f $(HTML_HELP) 169.20 - 169.21 -all: help_html
170.1 --- a/locale/help/area.show.de.txt Thu Jul 10 01:02:43 2014 +0200 170.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 170.3 @@ -1,15 +0,0 @@ 170.4 -= Themenbereich = 170.5 - 170.6 -Hier finden sich jeweils unter: 170.7 -- **Letzte Ereignisse:** Alle Ereignisse im Themenbereich 170.8 -- **Offene Themen:** Alle Themen des Themenbereichs, die zur Zeit offen sind, also Neu, in Diskussion, Eingefroren oder in Abstimmung 170.9 -- **Geschlossene Themen:** Alle Themen des Themenbereichs, die bereits abgestimmt sind oder die abgebrochen wurden 170.10 -- **Teilnehmer:** Stimmberechtigte, die sich dazu entschieden haben, sich im Themenbereich einzubringen 170.11 -- **Delegationen:** Auf Themenbereichsebene gesetzte Delegationen (Delegationen auf darüberliegender Gliederungsebene, sowie Delegationen auf darunterliegender Themenebene werden hier nicht aufgeführt) 170.12 - 170.13 -Sofern die Stimmberechtigung in der Gliederung vorhanden ist, kann man sich durch einen Klick auf "An diesem Themengebiet teilnehmen" als Teilnehmer des Themengebietes eintragen. Dies hat folgende Konsequenzen: 170.14 -- Der jeweilige Themenbereich wird auf der Startseite unter "Meine Themengebiete" angezeigt. 170.15 -- Man zählt zur Grundgesamtheit der Diskussionsteilnehmer von Themen im Themengebiet. Dies wirkt sich auf das von Initiativen zu erreichende Unterstützerquorum aus. 170.16 -- Benachrichtigungen zu Ereignissen im jeweiligen Themenbereich werden verschickt, sofern die Benachrichtigungseinstellungen entsprechend eingestellt sind. Die Benachrichtigungseinstellungen finden sich unter "Einstellungen" im Benutzermenü ganz rechts oben. 170.17 - 170.18 -Delegationen im Themenbereich wirken sich auf alle Themen aus, bei denen keine abweichende Delegationseinstellung vermerkt ist. Ist keine Delegationseinstellung im Themenbereich vorhanden, gilt ggf. eine Delegation auf Gliederungsebene. Bei eigenem Interesse an einem Thema, wird eine eventuell vorhandene Delegation zunächst ausgesetzt. Ebenso werden Delegationen dort ausgesetzt, wo man selbst an der Endabstimmung teilnimmt.
171.1 --- a/locale/help/area.show.el.txt Thu Jul 10 01:02:43 2014 +0200 171.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 171.3 @@ -1,21 +0,0 @@ 171.4 -==Τομέας== 171.5 -Παρουσίαση ενός τομέα με τα θέματα που υπάγονται σ' αυτόν. Μπορείτε να αναθέσετε έναν ολόκληρο τομέα σε κάποιο άλλο μέλος από τις επαφές σας, ώστε να σας αντιπροσωπεύει με την ψήφο του στα θέματα του τομέα αυτού. Μπορείτε να ακυρώσετε ή να αλλάξετε τέτοια ανάθεση οποιαδήποτε στιγμή, για όλο τον τομέα ή μόνο για συγκεκριμένα θέματα. 171.6 - 171.7 -Εδώ μπορείτε επίσης να δηλώσετε συμμετοχή στον τομέα ή και να ανοίξετε ένα νέο θέμα και να εισηγηθείτε μία πρωτοβουλία. 171.8 - 171.9 -Η δήλωση συμμετοχής στον τομέα έχει τις εξής συνέπειες: 171.10 -- Ο τομέας θα εμφανίζεται στην κεντρική σας σελίδα κάτω από το "Οι τομείς μου" 171.11 -- Προσμετράστε στο βασικό σύνολο για τις συζητήσεις των θεμάτων. Αυτό έχει επιπτώσεις στην απαρτία υποστηρικτών που πρέπει να συμπληρώσουν οι πρωτοβουλίες. 171.12 -- Θα λαμβάνετε ειδοποιήσεις μέσω email για τα συμβάντα στον τομέα, εφόσον το έχετε επιλέξει και στις ρυθμίσεις ειδοποιήσεων. Μπορείτε να δείτε και να αλλάξετε τις ρυθμίσεις ειδοποιήσεων πηγαίνοντας στο "Επιλογές", στο μενού χρήστη στην πάνω δεξιά γωνία. 171.13 - 171.14 -=Συμβάντα= 171.15 -Παρουσίαση των γεγονότων στον τομέα, με χρονολογική σειρά. 171.16 - 171.17 -=Θέματα= 171.18 -Όλα τα θέματα που ανήκουν σ' αυτόν τον τομέα, διαχωρισμένα σε <<κλειστά>> που έχουν καταλήξει και σε <<ανοιχτά>>, που βρίσκονται σε διαβούλευση ή ψηφοφορία ή σε κάποιο άλλο στάδιο. 171.19 - 171.20 -=Συμμετέχοντες= 171.21 -Κατάλογος όλων των μελών που έχουν δηλώσει συμμετοχή σε αυτόν τον τομέα. 171.22 - 171.23 -=Αναθέσεις= 171.24 -Παρουσίαση των αναθέσεων για αυτόν τον τομέα. Δείχνει τα μέλη και τους αντιπροσώπους που έχουν ορίσει. 171.25 \ No newline at end of file
172.1 --- a/locale/help/area.show.en.txt Thu Jul 10 01:02:43 2014 +0200 172.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 172.3 @@ -1,15 +0,0 @@ 172.4 -= Subject area = 172.5 - 172.6 -Here you find: 172.7 -- **Latest events:** Events in this subject area 172.8 -- **Open issues:** Issues of this subject area, which are currently open, i.e. new, in discussion, frozen or for voting 172.9 -- **Closed issues:** Issues of this subject area, where voting has been finished, or which have been canceled 172.10 -- **Participants:** Eligible voters, who decided to participate in this subject area 172.11 -- **Delegations:** Delegation settings of other members for this subject area (unit delegations and issue delegations are not listed here) 172.12 - 172.13 -As long as you're an eligible voter, you can indicate that you want to participate in this subject area. Click on "Participate in this area", if you want to do that. This has the following consequences: 172.14 -- The subject area will be shown on your homepage under the tab "My areas". 172.15 -- You are counted for the basic population for issue discussions. This has an impact on the supporter quorum, which initiatives have to reach. 172.16 -- E-mail notifies about events in the subject area will be sent, as long as your notification settings are configured respectively. Your notification settings can be changed by clicking on "Settings" in the user menu at the upper right corner. 172.17 - 172.18 -Your delegation of the subject area has an effect on all issues, where no divergent issue delegation has been set by you. When you do not set a delegation in the subject area, your delegation for the organizational unit may be in effect. If you're interested in an issue yourself, then potentially existent delegations will be postponed until voting. Voting on an issue cancels an existent delegation.
173.1 --- a/locale/help/area.show.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 173.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 173.3 @@ -1,15 +0,0 @@ 173.4 -= 领域 = 173.5 - 173.6 -您所看到的: 173.7 -- **最新动态:** 此领域的新动态 173.8 -- **开放性议题:** 目前在此领域仍开放的议题,可能处于新增、讨论中、底定或表决阶段。 173.9 -- **已结案议题:** 在此领域已经表决或被撤销的议题 173.10 -- **参与者:** 决定参与此领域的合格投票人 173.11 -- **委任清单:** 本领域的其他参与者所设置的委任(单位及议题委任不在此列) 173.12 - 173.13 -只要您是一个合格投票人,您可设定您是否要参与此领域。若您有此意愿,请点选「参与此领域」。之后将有下列变化: 173.14 -- 此领域将被显示在您首页的「我的领域」标签下。 173.15 -- 您将被计入此议题的讨论人数。这将影响提案必须通过的支持者决定门槛。 173.16 -- 只要您的通知设定允许,您将收到此领域的动态电邮通知。您可点选右上方使用者目录的「设定」连结以更改通知设定。 173.17 - 173.18 -您对此领域的委任将影响所有您未设定个别委任的议题,当您不对此领域设定委任,您对组织单位的委任设定将生效。若您关心个别议题,则潜在存在的委任将延后至表决。对个别议题进行表决则取消已设定的委任。 173.19 \ No newline at end of file
174.1 --- a/locale/help/area.show.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 174.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 174.3 @@ -1,15 +0,0 @@ 174.4 -= 領域 = 174.5 - 174.6 -您所看到的: 174.7 -- **最新動態:** 此領域的新動態 174.8 -- **開放性議題:** 目前在此領域仍開放的議題,可能處於新增、討論中、底定或表決階段。 174.9 -- **已結案議題:** 在此領域已經表決或被撤銷的議題 174.10 -- **參與者:** 決定參與此領域的合格投票人 174.11 -- **委任清單:** 本領域的其他參與者所設置的委任(單位及議題委任不在此列) 174.12 - 174.13 -只要您是一個合格投票人,您可設定您是否要參與此領域。若您有此意願,請點選「參與此領域」。之後將有下列變化: 174.14 -- 此領域將被顯示在您首頁的「我的領域」標籤下。 174.15 -- 您將被計入此議題的討論人數。這將影響提案必須通過的支持者決定門檻。 174.16 -- 只要您的通知設定允許,您將收到此領域的動態電郵通知。您可點選右上方使用者目錄的「設定」連結以更改通知設定。 174.17 - 174.18 -您對此領域的委任將影響所有您未設定個別委任的議題,當您不對此領域設定委任,您對組織單位的委任設定將生效。若您關心個別議題,則潛在存在的委任將延後至表決。對個別議題進行表決則取消已設定的委任。 174.19 \ No newline at end of file
175.1 --- a/locale/help/contact.list.de.txt Thu Jul 10 01:02:43 2014 +0200 175.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 175.3 @@ -1,4 +0,0 @@ 175.4 -=persönliche Kontaktliste= 175.5 -Um sie schneller auffinden zu können, kann man andere Mitglieder deiner persönlichen Kontaktliste hinzufügen. Auf der Profilseite des jeweiligen Mitglieds findet sich ein Link zum Hinzufügen. Falls man diesen Kontakt veröffentlicht, können andere sehen, dass dieses Mitglied auf der Kontaktliste vermerkt wurde. 175.6 - 175.7 -**Wichtig:** Zur Verbesserung des Bedienkomforts wird beim Delegieren die persönliche Kontaktliste angezeigt. Um an ein Mitglied delegieren zu können, musst es zunächst als Kontakt hinzugefügt werden. Das Löschen eines Kontaktes führt jedoch nicht zum Widerruf der Delegation.
176.1 --- a/locale/help/contact.list.el.txt Thu Jul 10 01:02:43 2014 +0200 176.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 176.3 @@ -1,10 +0,0 @@ 176.4 -==Προσωπική λίστα επαφών== 176.5 -Μπορείτε να προσθέσετε μέλη στις επαφές σας ώστε να τα βρίσκετε γρηγορότερα. Αυτό γίνεται με ένα σύνδεσμο που θα βρείτε στη σελίδα προφίλ του κάθε μέλους. 176.6 - 176.7 -//Για να δείτε όλα τα εγγεγραμμένα μέλη πηγαίνετε στην κεντρική σελίδα και πατήστε στο <<Μέλη>>.// 176.8 - 176.9 -=Δημοσίευση= 176.10 -Η λίστα των επαφών σας είναι προσωπική και δεν εμφανίζεται σε άλλους. Εάν επιλέξετε να δημοσιεύσετε κάποια από τα μέλη στις επαφές σας, τα μέλη αυτά θα εμφανίζονται δημόσια στη λίστα των επαφών σας. 176.11 - 176.12 -=Αναθέσεις= 176.13 -Για να μπορέσετε να αναθέσετε κάποια <<ενότητα>>, <<τομέα>> ή <<θέμα>> σε ένα μέλος θα πρέπει να το προσθέσετε πρώτα στις επαφές σας ώστε να εμφανίζεται στη λίστα της εντολής ανάθεσης. Αφαίρεση μελών από τις επαφές σας δεν ακυρώνει αναθέσεις που μπορεί να έχουν γίνει.
177.1 --- a/locale/help/contact.list.en.txt Thu Jul 10 01:02:43 2014 +0200 177.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 177.3 @@ -1,4 +0,0 @@ 177.4 -=personal list of contacts= 177.5 -In order to find other members more quickly, you can add them to your personal list of contacts. On the profile page of the respective member you will find a link for doing so. If you publish a contact, others can see this member as listed on your list of contacts. 177.6 - 177.7 -**Important:** For improved ease-of-use your list of contacts will be shown to you when you delegate. In order to delegate to a member, you must first add him or her to your contacts. Removing a contact does not revoke the delegation, though.
178.1 --- a/locale/help/contact.list.eo.txt Thu Jul 10 01:02:43 2014 +0200 178.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 178.3 @@ -1,4 +0,0 @@ 178.4 -=Persona kontaktlisto= 178.5 -Vi povas aldoni aliajn membrojn al via persona kontaktlisto, por ke vi trovu ilin pli rapide. En la profilpaĝo de la respektiva membro vi trovas ligilon por aldoni. Se vi publikigas kontakton, aliaj povas vidi, ke tiu ĉi membro estas en via kontaktlisto. 178.6 - 178.7 -**Grave:** Por pliigi vian komforton, oni montras al vi dum delegado vian personan kontaktliston. Por povi delegi al membro vi devas unue aldoni lin kiel kontakton. Nuligi kontakton tamen ne kaŭzas revokon de la delegacio.
179.1 --- a/locale/help/contact.list.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 179.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 179.3 @@ -1,4 +0,0 @@ 179.4 -=个人通讯录列表= 179.5 -为了更快速找到其他成员,您可将他们加入您的个人通讯录。您可在个别成员的个人简介页找到连结以加入。若您公开一个连络人,其他人将可看到这位成员被列在您的通讯录中。 179.6 - 179.7 -**重要事项:** 为了使用方便,您的通讯录列表将会在您指定委任时显示。要委任一位成员,您必须先加他为您的联络人。但将委任人自通讯录移除并不会撤回委任。 179.8 \ No newline at end of file
180.1 --- a/locale/help/contact.list.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 180.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 180.3 @@ -1,4 +0,0 @@ 180.4 -=個人通訊錄列表= 180.5 -為了更快速找到其他成員,您可將他們加入您的個人通訊錄。您可在個別成員的個人簡介頁找到連結以加入。若您公開一個連絡人,其他人將可看到這位成員被列在您的通訊錄中。 180.6 - 180.7 -**重要事項:** 為了使用方便,您的通訊錄列表將會在您指定委任時顯示。要委任一位成員,您必須先加他為您的聯絡人。但將委任人自通訊錄移除並不會撤回委任。 180.8 \ No newline at end of file
181.1 --- a/locale/help/delegation.new.area.de.txt Thu Jul 10 01:02:43 2014 +0200 181.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 181.3 @@ -1,5 +0,0 @@ 181.4 -= Delegation für diesen Themenbereich = 181.5 - 181.6 -Man kann die eigene Stimme für diesen Themenbereich (unabhängig von der Mitgliedschaft im Themenbereich) an eine Person in der persönlichen Kontaktliste delegieren. Diese Delegation hat gegenüber einer eventuell vorhandenen Gliederungsdelegation Vorrang, gilt jedoch nur dann, wenn keine eigene Beteiligung am Thema besteht bzw. nicht selbst abgestimmt wird und man für das jeweilige Thema keine themenspezifische Delegation erteilt hat. 181.7 - 181.8 -**Achtung:** Delegieren kann man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
182.1 --- a/locale/help/delegation.new.area.el.txt Thu Jul 10 01:02:43 2014 +0200 182.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 182.3 @@ -1,4 +0,0 @@ 182.4 -=Ανάθεση τομέα= 182.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτόν τον τομέα (ανεξάρτητα από τη συμμετοχή σας στον τομέα) σε ένα άτομο από τη λίστα επαφών σας. Μπορείτε να προσθέσετε άτομα στις επαφές σας πηγαίνοντας στην περιοχή <<Μέλη>>, στην κεντρική σελίδα ή στην περιοχή <<Συμμετέχοντες>> του τρέχοντος τομέα. 182.6 - 182.7 -Η ανάθεση αυτή υπερισχύει μιας πιθανής καθολικής ανάθεσης αλλά μόνο στην περίπτωση που δεν συμμετέχετε προσωπικά και όταν πρόκειται για κάποιο <<θέμα>> το οποίο δεν έχετε αναθέσει πιο συγκεκριμένα. Για να αναθέσετε συγκεκριμένα θέματα του τομέα, παρακαλώ πηγαίνετε στη σελίδα τους. 182.8 \ No newline at end of file
183.1 --- a/locale/help/delegation.new.area.en.txt Thu Jul 10 01:02:43 2014 +0200 183.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 183.3 @@ -1,5 +0,0 @@ 183.4 -= Delegation for this area = 183.5 - 183.6 -You can delegate your vote for this area (independent of your membership in the area) to a person on your contact list. This delegation takes precedence over a potentially existing global delegation, but only, if you don't participate yourself and if you have not given a issue-specific delegation for the respective issue. Please go to the respective issue page for making issue-specific delegations. 183.7 - 183.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
184.1 --- a/locale/help/delegation.new.area.eo.txt Thu Jul 10 01:02:43 2014 +0200 184.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 184.3 @@ -1,5 +0,0 @@ 184.4 -= Delegacio pri tiu ĉi temaro = 184.5 - 184.6 -Vi povas delegi vian voĉon por tiu ĉi temaro (sendepende de via membreco en tiu ĉi temaro) al persono en via kontaktlisto. Tiu ĉi delegacio rangas antaŭ ebla ĝenerala delegacio, sed nur se vi ne mem partoprenas kaj vi ne delegis teman delegacion pri la respektiva temo. Por tema delegado bonvolu ŝanĝi al la respektiva tempaĝo. Vi povas delegi nur al membroj de via kontaktlisto. 184.7 - 184.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
185.1 --- a/locale/help/delegation.new.area.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 185.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 185.3 @@ -1,5 +0,0 @@ 185.4 -= 领域委任 = 185.5 - 185.6 -不论您是否有此领域的成员身份,您可委任您的表决给您通讯录中的一位联络人。此委任,在您本身不参与表决或您并未对个别议题指定委任的状况下,会优先于一个可能已存在的全面委任。若您要对个别议题进行委任,请前往该议题页面。 185.7 - 185.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。 185.9 \ No newline at end of file
186.1 --- a/locale/help/delegation.new.area.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 186.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 186.3 @@ -1,5 +0,0 @@ 186.4 -= 領域委任 = 186.5 - 186.6 -不論您是否有此領域的成員身份,您可委任您的表決給您通訊錄中的一位聯絡人。此委任,在您本身不參與表決或您並未對個別議題指定委任的狀況下,會優先於一個可能已存在的全面委任。若您要對個別議題進行委任,請前往該議題頁面。 186.7 - 186.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。 186.9 \ No newline at end of file
187.1 --- a/locale/help/delegation.new.issue.de.txt Thu Jul 10 01:02:43 2014 +0200 187.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 187.3 @@ -1,4 +0,0 @@ 187.4 -= Delegation für dieses Thema = 187.5 -Eine Delegation zu diesem Thema geht einer eventuell vorhandenen globalen Delegation und/oder Delegation für den übergeordneten Themenbereich vor. Bei angemeldetem Interesse werden ausgehende Delegationen während der Phasen ,,Neu'', ,,Diskussion'' und ,,Eingefroren'' ausgesetzt, gelten aber in der Endabstimmung, sofern nicht selbst abgestimmt wird. 187.6 - 187.7 -**Achtung:** Delegieren kannst man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
188.1 --- a/locale/help/delegation.new.issue.el.txt Thu Jul 10 01:02:43 2014 +0200 188.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 188.3 @@ -1,4 +0,0 @@ 188.4 -=Ανάθεση θέματος= 188.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτό το θέμα σε κάποιο άτομο από τη λίστα επαφών σας. Για να προσθέσετε άτομα στις επαφές σας πηγαίνετε στην περιοχή <<Μέλη>>, στην κεντρική σελίδα. 188.6 - 188.7 -Η ανάθεση αυτή υπερισχύει μιας πιθανής καθολικής ανάθεσης ή ανάθεσης τομέα ή ενότητας που μπορεί να ισχύει. Εάν έχετε δηλώσει το ενδιαφέρον σας για αυτό το θέμα, η εξερχόμενη ανάθεση //(δηλαδή όταν εσείς επιλέγετε κάποιον άλλο ως αντιπρόσωπό σας για το <<θέμα>>)// θα ανασταλεί κατά το στάδιο συζήτησης, αλλά θα είναι ενεργή κατά την ψηφοφορία.
189.1 --- a/locale/help/delegation.new.issue.en.txt Thu Jul 10 01:02:43 2014 +0200 189.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 189.3 @@ -1,5 +0,0 @@ 189.4 -= Delegation for this issue = 189.5 - 189.6 -A delegation for this issue takes precedence over a potentially existing global delegation and/or a delegation for the superior area. If you added your interest outgoing delegations will be suspended during the discussion phase, but will be active during the final voting. You can only delegate to members on your contact list. You can extend the contact list anytime in the ,,Members'' area. 189.7 - 189.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
190.1 --- a/locale/help/delegation.new.issue.eo.txt Thu Jul 10 01:02:43 2014 +0200 190.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 190.3 @@ -1,5 +0,0 @@ 190.4 -= Delegacio pri tiu ĉi temo = 190.5 - 190.6 -Delegacio pri tiu ĉi temo rangas antaŭ ebla ĝenerala delegacio kaŭ delegacio pri la supera temaro. Kaze de anoncita intereso, la elirantaj delegacioj estas malebligitaj dum la diskutfazo, sed validas ĉe la fina voĉdono. Vi povas delegi nur al membroj de via kontaktlisto. 190.7 - 190.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
191.1 --- a/locale/help/delegation.new.issue.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 191.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 191.3 @@ -1,5 +0,0 @@ 191.4 -= 议题委任 = 191.5 - 191.6 -对此议题的委任会优先于可能已存在的全面委任或更高阶的领域委任。若您关心此议题,则所送出的委任将在讨论期被暂停,直到最后表决时再次启用。您只能委任给您通讯录中的联络人。您可在任何时候自「成员」页面延伸您的通讯录。 191.7 - 191.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。 191.9 \ No newline at end of file
192.1 --- a/locale/help/delegation.new.issue.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 192.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 192.3 @@ -1,5 +0,0 @@ 192.4 -= 議題委任 = 192.5 - 192.6 -對此議題的委任會優先於可能已存在的全面委任或更高階的領域委任。若您關心此議題,則所送出的委任將在討論期被暫停,直到最後表決時再次啟用。您只能委任給您通訊錄中的聯絡人。您可在任何時候自「成員」頁面延伸您的通訊錄。 192.7 - 192.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。 192.9 \ No newline at end of file
193.1 --- a/locale/help/delegation.new.unit.de.txt Thu Jul 10 01:02:43 2014 +0200 193.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 193.3 @@ -1,5 +0,0 @@ 193.4 -= Delegation für Gliederung = 193.5 - 193.6 -Die Delegation für eine Gliederung gilt immer dann, wenn man sich nicht selbst beteiligt und es keine Delegation auf der Ebene des jeweiligen Themenbereichs oder des Themas gibt. Beachte, dass Delegationen für eine übergeordnete Gliederungsebene nicht automatisch für untergeordnete Gliederungsebenen gelten. 193.7 - 193.8 -**Achtung:** Delegieren kannst man nur an Mitglieder in der eigenen Kontaktliste. Um ein Mitglied zur Kontaktliste hinzuzufügen ist die Seite des jeweiligen Mitglieds aufzurufen. Diese findet man z.B. in der jeweiligen Gliederung unter dem Reiter ,,Stimmberechtigte''. Durch einen Klick auf den Benutzer gelangt man zur Seite des jeweiligen Mitglieds, auf der man dieses Mitglied zu den persönlichen Kontakten hinzufügen kann.
194.1 --- a/locale/help/delegation.new.unit.el.txt Thu Jul 10 01:02:43 2014 +0200 194.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 194.3 @@ -1,6 +0,0 @@ 194.4 -=Ανάθεση ενότητας= 194.5 -Μπορείτε να εκχωρήσετε την ψήφο σας για αυτήν την ενότητα σε κάποιο άτομο από τη λίστα επαφών σας. Για να προσθέσετε άτομα στις επαφές σας πηγαίνετε στην περιοχή <<Μέλη>>, στην κεντρική σελίδα. 194.6 - 194.7 -Η ανάθεση αυτή ισχύει σε κάθε περίπτωση που δεν συμμετέχετε προσωπικά και δεν υπάρχει πιο εξειδικευμένη ανάθεση σε επίπεδο <<τομέα>> ή <<θέματος>>. 194.8 - 194.9 -Η ανάθεση μίας ενότητας δεν κληρονομείται αυτόματα από πιθανές υπο-ενότητές της. 194.10 \ No newline at end of file
195.1 --- a/locale/help/delegation.new.unit.en.txt Thu Jul 10 01:02:43 2014 +0200 195.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 195.3 @@ -1,5 +0,0 @@ 195.4 -= Unit delegation = 195.5 - 195.6 -A unit delegation is always active if you don't participate yourself and there is no delegation on the level of the respective area or issue. Note that unit delegations for a superordinate unit are not automatically inherited to subdivisions. 195.7 - 195.8 -**Notice:** You can only delegate to members, who you have added to your list of contacts. You can find other members under the tabulator ""Eligible voters"" in their corresponding unit. Click on the member to visit their member page, then click on ""Add to my contacts"" to add this member to your personal contact list.
196.1 --- a/locale/help/delegation.new.unit.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 196.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 196.3 @@ -1,5 +0,0 @@ 196.4 -= 单位委任 = 196.5 - 196.6 -若您本身并未直接参与(关心)特定议题或是设定特定领域或议题的委任,单位委任就总是有效的。请注意对一个较高层的单位委任并不自动传承给其次级单位。 196.7 - 196.8 -**注意:** 您只可委任给您已加入通讯录的成员。 ?您可在各相关单位页面的「合格投票人」页签找到其他成员。点击各成员连结以拜访他们的成员专页,然后点击「加入通讯录」将此成员加入您的个人联络人列表。 196.9 \ No newline at end of file
197.1 --- a/locale/help/delegation.new.unit.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 197.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 197.3 @@ -1,5 +0,0 @@ 197.4 -= 單位委任 = 197.5 - 197.6 -若您本身並未直接參與(關心)特定議題或是設定特定領域或議題的委任,單位委任就總是有效的。請注意對一個較高層的單位委任並不自動傳承給其次級單位。 197.7 - 197.8 -**注意:** 您只可委任給您已加入通訊錄的成員。您可在各相關單位頁面的「合格投票人」頁籤找到其他成員。點擊各成員連結以拜訪他們的成員專頁,然後點擊「加入通訊錄」將此成員加入您的個人聯絡人列表。
198.1 --- a/locale/help/index.check_delegations.de.txt Thu Jul 10 01:02:43 2014 +0200 198.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 198.3 @@ -1,1 +0,0 @@ 198.4 -Dieses System ist so konfiguriert, dass Teilnehmer aufgefordert werden ihre Delegationen für Gliederungen und Themengebiete regelmäßig zu überprüfen und zu bestätigen. Hierzu sind diese in der folgenden Liste aufgeführt. Ein Klick auf "Delegationsprüfung abschließen" vervollständigt den Vorgang. 198.5 \ No newline at end of file
199.1 --- a/locale/help/index.check_delegations.en.txt Thu Jul 10 01:02:43 2014 +0200 199.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 199.3 @@ -1,1 +0,0 @@ 199.4 -This system is configured to advise members to check and confirm their unit and area delegations regularly. To do so please check your outgoing delegations for units and areas as listed below. Click on "Finish delegation check" to complete this procedure. 199.5 \ No newline at end of file
200.1 --- a/locale/help/index.check_delegations_hard.de.txt Thu Jul 10 01:02:43 2014 +0200 200.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 200.3 @@ -1,1 +0,0 @@ 200.4 -Dieses System ist so konfiguriert, dass Teilnehmer gezwungen sind ihre Delegationen für Gliederungen und Themengebiete regelmäßig zu überprüfen und zu bestätigen. Hierzu sind diese in der folgenden Liste aufgeführt. Ein Klick auf "Delegationsprüfung abschließen" vervollständigt den Vorgang. 200.5 \ No newline at end of file
201.1 --- a/locale/help/index.check_delegations_hard.en.txt Thu Jul 10 01:02:43 2014 +0200 201.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 201.3 @@ -1,1 +0,0 @@ 201.4 -This system is configured to enforce members to check and confirm their unit and area delegations regularly. To do so please check your outgoing delegations for units and areas as listed below. Click on "Finish delegation check" to complete this procedure. 201.5 \ No newline at end of file
202.1 --- a/locale/help/index.download.de.txt Thu Jul 10 01:02:43 2014 +0200 202.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 202.3 @@ -1,3 +0,0 @@ 202.4 -= Download der Datenbank = 202.5 - 202.6 -Im Interesse der Nachvollziehbarkeit ist es jedem Mitglied möglich, eine Kopie der gesamten Datenbank herunterzuladen. Hierbei werden jedoch aus Sicherheits- und Datenschutzgründen bestimmte Informationen (z.B. Passwörter und E-Mail-Adressen) entfernt. Das Dateiformat ist gzip-komprimiertes SQL für die Datenbank PostgreSQL.
203.1 --- a/locale/help/index.download.el.txt Thu Jul 10 01:02:43 2014 +0200 203.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 203.3 @@ -1,4 +0,0 @@ 203.4 -==Λήψη βάσης δεδομένων== 203.5 -Οποιοδήποτε μέλος μπορεί να κατεβάσει ένα αντίγραφο ολόκληρης της βάσης δεδομένων και να το ελέγξει. Για λόγους ασφαλείας και προστασίας προσωπικών δεδομένων, κάποια στοιχεία (π.χ. κωδικοί πρόσβασης και διευθύνσεις email) θα λείπουν. 203.6 - 203.7 -Τα δεδομένα είναι σε μορφή SQL (για PostgreSQL) και είναι συμπιεσμένα με το gzip.
204.1 --- a/locale/help/index.download.en.txt Thu Jul 10 01:02:43 2014 +0200 204.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 204.3 @@ -1,3 +0,0 @@ 204.4 -= Database download = 204.5 - 204.6 -For auditability reasons all members can download a copy of the entire database. But for security and data privacy reasons certain data (e.g. passwords and email addresses) will be lacking. The data format is SQL as used for the PostgreSQL database compressed with gzip.
205.1 --- a/locale/help/index.download.eo.txt Thu Jul 10 01:02:43 2014 +0200 205.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 205.3 @@ -1,3 +0,0 @@ 205.4 -= Elŝuto de la datumbazo = 205.5 - 205.6 -Por plua evaluado ĉiu membro povas elŝuti kopion de la tuta datumbazo. Ĉe tio tamen certaj informoj (ekzemple pasvortoj kaj retpoŝtadresoj) estas forviŝitaj pro sekurecaj kaj datumprotektaj kialoj. La datumformato estas gzip-kunpremita SQL por la datumbazo PostgreSQL.
206.1 --- a/locale/help/index.download.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 206.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 206.3 @@ -1,3 +0,0 @@ 206.4 -= 下载资料库 = 206.5 - 206.6 -为了可审查性考量,所有成员可下载整个资料库的一份备份。但为了安全及资料隐私考量,某些资料(例如:密码及电邮地址)将从缺。资料格式为如同 PostgreSQL 资料库所使用的 SQL,并使用 gzip 压缩。 206.7 \ No newline at end of file
207.1 --- a/locale/help/index.download.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 207.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 207.3 @@ -1,3 +0,0 @@ 207.4 -= 下載資料庫 = 207.5 - 207.6 -為了可審查性考量,所有成員可下載整個資料庫的一份備份。但為了安全及資料隱私考量,某些資料(例如:密碼及電郵地址)將從缺。資料格式為如同 PostgreSQL 資料庫所使用的 SQL,並使用 gzip 壓縮。 207.7 \ No newline at end of file
208.1 --- a/locale/help/index.index.de.txt Thu Jul 10 01:02:43 2014 +0200 208.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 208.3 @@ -1,12 +0,0 @@ 208.4 -= Willkommen bei LiquidFeedback und auf deiner Startseite = 208.5 -Überall im System finden sich Kästen wie dieser mit Hilfetexten. Man kann jeden Hilfetext mit einem Klick auf "Diesen Hilfetext ausblenden" rechts oben im gelben Kasten ausblenden und durch einen Klick auf das kleine blaue Fragezeichen oben in der Menüzeile wieder einblenden. 208.6 - 208.7 -Unten finden sich folgende Ansichten: 208.8 -- **Startseite:** Eine Unterauswahl zwischen: 208.9 --- **Meine Themengebiete:** Themenbereiche, an denen teilgenommen wird 208.10 --- **Alle Themengebiete in meinen Gliederungen:** alle Themenbereiche in Gliederungen mit Stimmberechtigung 208.11 --- **Alle Gliederungen:** Alle Gliederungen, unabhängig von der Stimmberechtigung 208.12 -- **Letzte Ereignisse:** Ereignisse aus den eigenen Themenbereichen und Themen sowie die globale Zeitlinie 208.13 -- **Offene Themen:** Alle Themen, die zur Zeit offen sind, also Neu, in Diskussion, Eingefroren oder in Abstimmung 208.14 -- **Geschlossene Themen:** Alle Themen, die bereits abgestimmt sind oder die abgebrochen wurden 208.15 -- **Mitglieder:** Alle aktiven Mitglieder. Nach einem Klick auf ein bestimmtes Mitglied kann man dieses zur persönlichen Kontaktliste hinzufügen, um später an dieses Mitglied delegieren zu können.
209.1 --- a/locale/help/index.index.el.txt Thu Jul 10 01:02:43 2014 +0200 209.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 209.3 @@ -1,12 +0,0 @@ 209.4 -=Καλώς ήρθατε στο Liquid Feedback και στην αρχική σας σελίδα= 209.5 -Αυτά τα κίτρινα πλαίσια με τα βοηθητικά κείμενα θα σας ακολουθούν μέχρι να τα αποκρύψετε σταδιακά, ενώ αν χρειαστεί μπορείτε να τα επαναφέρετε εύκολα κάνοντας κλικ στο εικονίδιο βοήθειας. 209.6 - 209.7 -Εδώ θα βρείτε: 209.8 - 209.9 -- Κεντρική Σελίδα 209.10 --- Τους τομείς που σας ενδιαφέρουν 209.11 --- Όλους τους τομείς στις ενότητες που έχετε δικαίωμα ψήφου 209.12 --- Όλες τις ενότητες 209.13 -- Πρόσφατα συμβάντα από τους τομείς που σας ενδιαφέρουν καθώς και σε όλο το σύστημα 209.14 -- Όλα τα θέματα, διαχωρισμένα σε <<κλειστά>> που έχουν καταλήξει και σε <<ανοιχτά>> που βρίσκονται σε διαβούλευση ή ψηφοφορία ή σε κάποιο άλλο στάδιο. 209.15 -- Όλα τα ενεργά μέλη, τα οποία μπορείτε να προσθέσετε στις επαφές σας ώστε να μπορείτε να τους ορίσετε ως αντιπροσώπους σας αναθέτοντάς τους κάποια ενότητα, τομέα ή συγκεκριμένο θέμα.
210.1 --- a/locale/help/index.index.en.txt Thu Jul 10 01:02:43 2014 +0200 210.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 210.3 @@ -1,12 +0,0 @@ 210.4 -= Welcome to LiquidFeedback and your homepage = 210.5 -All over the system, you'll find these boxes with help texts. You can switch off each help text, by clicking on "hide this help message" in the upper right corner of the yellow box, and switch it on again, by clicking on the small blue question mark in the menu bar above. 210.6 - 210.7 -Below you find: 210.8 -- **Home:** 210.9 --- **My areas:** subject areas you want to participate in 210.10 --- **All areas in my units:** All subject areas of those organizational units you're eligible voter in 210.11 --- **All units:** All organizational units 210.12 -- **Latest events:** Events in your subject areas and your issues, as well as the global timeline 210.13 -- **Open issues:** All issues, which are currently open, i.e. new, in discussion, frozen or for voting 210.14 -- **Closed issues:** All issues, where voting has been finished, or which have been canceled 210.15 -- **Members:** All active members. After you clicking on a particular member, you can add this member to your personal contact list, in order to be able to delegate to that member.
211.1 --- a/locale/help/index.index.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 211.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 211.3 @@ -1,12 +0,0 @@ 211.4 -= 欢迎莅临 LiquidFeedback 及您的首页 = 211.5 -在整个系统内,您将看到这些说明文件的框架。您可点击黄色框架右上角的「隐藏此说明文件」来个别关闭说明文件,或点击上方选单栏的小蓝问号圈以再次启用。 211.6 - 211.7 -以下您将看到: 211.8 -- **首页:** 211.9 --- **我的领域:** 您想参与的主题领域 211.10 --- **我单位中所有领域:** 所有您为合格投票人的组织单位中的主题领域 211.11 --- **所有单位:** 所有的组织性单位 211.12 -- **最新动态:** 您的领域及议题的动态,以及完整的时间轴显示。 211.13 -- **开放性议题:** 所有目前仍开放的议题,意即:递交期议题、讨论期议题、底定期议题或表决中议题。 211.14 -- **已结案议题:** 所有表决已完成或是已被取消的议题。 211.15 -- **成员** 所有活动的成员。您可点选特定成员,加入您的通讯录,便得以委任给该成员。 211.16 \ No newline at end of file
212.1 --- a/locale/help/index.index.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 212.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 212.3 @@ -1,12 +0,0 @@ 212.4 -= 歡迎蒞臨 LiquidFeedback 及您的首頁 = 212.5 -在整個系統內,您將看到這些說明文件的框架。您可點擊黃色框架右上角的「隱藏此說明文件」來個別關閉說明文件,或點擊上方選單欄的小藍問號圈以再次啓用。 212.6 - 212.7 -以下您將看到: 212.8 -- **首頁:** 212.9 --- **我的領域:** 您想參與的主題領域 212.10 --- **我單位中所有領域:** 所有您為合格投票人的組織單位中的主題領域 212.11 --- **所有單位:** 所有的組織性單位 212.12 -- **最新動態:** 您的領域及議題的動態,以及完整的時間軸顯示。 212.13 -- **開放性議題:** 所有目前仍開放的議題,意即:遞交期議題、討論期議題、底定期議題或表決中議題。 212.14 -- **已結案議題:** 所有表決已完成或是已被取消的議題。 212.15 -- **成員** 所有活動的成員。您可點選特定成員,加入您的通訊錄,便得以委任給該成員。
213.1 --- a/locale/help/initiative.add_initiator.de.txt Thu Jul 10 01:02:43 2014 +0200 213.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 213.3 @@ -1,3 +0,0 @@ 213.4 -= Initiator einladen = 213.5 - 213.6 -Hier kannst du eine Person aus deiner Kontaktliste zur gleichberechtigten Mitarbeit am Entwurf einladen. Der eingeladene muss die Einladung erst akzeptieren, bevor er als weiterer Initiator gilt (und angezeigt wird). **Vorsicht:** Alle Initiatoren haben die gleichen Rechte und können andere Initiatoren entfernen.
214.1 --- a/locale/help/initiative.add_initiator.el.txt Thu Jul 10 01:02:43 2014 +0200 214.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 214.3 @@ -1,4 +0,0 @@ 214.4 -==Πρόσκληση νέου εισηγητή== 214.5 -Εδώ μπορείτε να προσκαλέσετε ένα άτομο από τη λίστα επαφών σας για να συνεργαστείτε με ίσα δικαιώματα στο προσχέδιο. Το μέλος που θα καλέσετε πρέπει πρώτα να αποδεχτεί την πρόσκληση για να γίνει και να εμφανίζεται ως εισηγητής. 214.6 - 214.7 -**Προσοχή:** Όλοι οι εισηγητές έχουν τα ίδια δικαιώματα και μπορούν να αφαιρέσουν άλλους εισηγητές. 214.8 \ No newline at end of file
215.1 --- a/locale/help/initiative.add_initiator.en.txt Thu Jul 10 01:02:43 2014 +0200 215.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 215.3 @@ -1,3 +0,0 @@ 215.4 -= Invite initiator = 215.5 - 215.6 -Here you can invite a person on your contact list to collaborate with equal rights on the draft. The invited member must first accept the invitation in order to become an initiator (and be displayed as such). **Attention:** All initiators have the same rights and can remove other initiators.
216.1 --- a/locale/help/initiative.add_initiator.eo.txt Thu Jul 10 01:02:43 2014 +0200 216.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 216.3 @@ -1,3 +0,0 @@ 216.4 -= Inviti inicionton = 216.5 - 216.6 -Ĉi tie vi povas inviti personon de via kontaklisto al samrajta kunlaboro pri via skizo. La invitito devas unue akcepti la inviton, antaŭ ol li estas plua iniciinto (kaj estas listigita). **Atentu:** Ĉiuj iniciintoj havas la samajn rajtojn kaj povas forviŝi aliajn iniciintojn.
217.1 --- a/locale/help/initiative.add_initiator.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 217.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 217.3 @@ -1,3 +0,0 @@ 217.4 -= 邀请发起者 = 217.5 - 217.6 -在此您可邀请一位在您通讯录中的联络人来平权合作草案的编辑。被邀请的成员必须首先接受邀请才会成为(并被列为)发起者。 **注意:** 所有发起者有一样的权利并可移除其他发起者。 217.7 \ No newline at end of file
218.1 --- a/locale/help/initiative.add_initiator.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 218.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 218.3 @@ -1,3 +0,0 @@ 218.4 -= 邀請發起者 = 218.5 - 218.6 -在此您可邀請一位在您通訊錄中的聯絡人來平權合作草案的編輯。被邀請的成員必須首先接受邀請才會成為(並被列為)發起者。 **注意:** 所有發起者有一樣的權利並可移除其他發起者。
219.1 --- a/locale/help/initiative.remove_initiator.de.txt Thu Jul 10 01:02:43 2014 +0200 219.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 219.3 @@ -1,3 +0,0 @@ 219.4 -= Initiator entfernen = 219.5 - 219.6 -Du kannst dich oder einen anderen Initiator entfernen, sofern nach dem Entfernen noch mindestens ein Initiator existiert. Um die Initiative insgesamt aufzugeben, wähle bitte ,,Initiative zurückziehen''.
220.1 --- a/locale/help/initiative.remove_initiator.el.txt Thu Jul 10 01:02:43 2014 +0200 220.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 220.3 @@ -1,2 +0,0 @@ 220.4 -==Αφαίρεση εισηγητή== 220.5 -Μπορείτε να αφαιρέσετε τον εαυτό σας ή κάποιον άλλο εισηγητή μόνο εάν θα παραμείνει τουλάχιστον ένας. Για να ανακαλέσετε όλη την πρωτοβουλία, παρακαλώ επιλέξτε <<Ανάκληση πρωτοβουλίας>>. 220.6 \ No newline at end of file
221.1 --- a/locale/help/initiative.remove_initiator.en.txt Thu Jul 10 01:02:43 2014 +0200 221.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 221.3 @@ -1,3 +0,0 @@ 221.4 -= Remove initiator = 221.5 - 221.6 -You can remove yourself or another initiator, as long as after the removal there will be at least one initiator left. In order to abandon the entire initiative as such, please select ,,Revoke initiative''.
222.1 --- a/locale/help/initiative.remove_initiator.eo.txt Thu Jul 10 01:02:43 2014 +0200 222.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 222.3 @@ -1,3 +0,0 @@ 222.4 -= Forigi iniciinton = 222.5 - 222.6 -Vi povas forigi vin aŭ alian iniciinton, se post la forigo almenaŭ unu iniciinto ekzistos. Por nuligi la iniciaton entute, bonvolu elekti „nuligi iniciaton“.
223.1 --- a/locale/help/initiative.remove_initiator.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 223.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 223.3 @@ -1,3 +0,0 @@ 223.4 -= 移除发起者 = 223.5 - 223.6 -只要在移除后仍至少还有一位发起者,您可移除您自己或另一位发起者。若要停止整个提案,请选择「撤销提案」。 223.7 \ No newline at end of file
224.1 --- a/locale/help/initiative.remove_initiator.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 224.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 224.3 @@ -1,3 +0,0 @@ 224.4 -= 移除發起者 = 224.5 - 224.6 -只要在移除後仍至少還有一位發起者,您可移除您自己或另一位發起者。若要停止整個提案,請選擇「撤銷提案」。
225.1 --- a/locale/help/initiative.revoke.de.txt Thu Jul 10 01:02:43 2014 +0200 225.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 225.3 @@ -1,3 +0,0 @@ 225.4 -= Initiative zurückziehen = 225.5 - 225.6 -Du kannst diese Initiative zurückziehen. Dies kann nicht rückgängig gemacht werden. Natürlich hast du jederzeit die Möglichkeit, eine neue Initiative zu starten. Den Unterstützern kannst du eine alternative Initiative empfehlen. Angeboten werden dir hierfür alle von dir unterstützten Initiativen.
226.1 --- a/locale/help/initiative.revoke.el.txt Thu Jul 10 01:02:43 2014 +0200 226.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 226.3 @@ -1,4 +0,0 @@ 226.4 -==Ανάκληση πρωτοβουλίας== 226.5 -Μπορείτε να ανακαλέσετε αυτή την πρωτοβουλία. Αυτή η ανάκληση δεν είναι αναστρέψιμη, αλλά μπορείτε πάντα να ξεκινήσετε μία νέα πρωτοβουλία. 226.6 - 226.7 -Σας δίνεται η δυνατότητα να προτείνετε στους υποστηρικτές μία εναλλακτική πρωτοβουλία, από αυτές που εσείς υποστηρίζετε. 226.8 \ No newline at end of file
227.1 --- a/locale/help/initiative.revoke.en.txt Thu Jul 10 01:02:43 2014 +0200 227.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 227.3 @@ -1,3 +0,0 @@ 227.4 -= Revoke initiative = 227.5 - 227.6 -You can revoke this initiative. This cannot be rolled back, but you can, of course, start a new initiative anytime. You can recommend the supporters an alternative initiative. For doing so you are offered all initiatives supported by you.
228.1 --- a/locale/help/initiative.revoke.eo.txt Thu Jul 10 01:02:43 2014 +0200 228.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 228.3 @@ -1,4 +0,0 @@ 228.4 -= Nuligi iniciaton = 228.5 - 228.6 -Vi povas nuligi iniciaton. Tio estas nemaligebla. Kompreneble, vi havas ĉiumomente la eblecon komenci novan iniciaton. Vi povas rekomendi alternativan iniciaton al la subtenintoj. Por tio vi povas elekti el ĉiuj viaj subtenataj iniciatoj. 228.7 -
229.1 --- a/locale/help/initiative.revoke.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 229.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 229.3 @@ -1,3 +0,0 @@ 229.4 -= 撤销提案 = 229.5 - 229.6 -您可撤销此提案。此动作不可复原,但您当然可在任何时间发起另一个新提案。您可向提案支持者推荐另一个提案。您可自所有所支持的提案中选择要推荐的提案。 229.7 \ No newline at end of file
230.1 --- a/locale/help/initiative.revoke.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 230.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 230.3 @@ -1,3 +0,0 @@ 230.4 -= 撤銷提案 = 230.5 - 230.6 -您可撤銷此提案。此動作不可復原,但您當然可在任何時間發起另一個新提案。您可向提案支持者推薦另一個提案。您可自所有所支持的提案中選擇要推薦的提案。
231.1 --- a/locale/help/initiative.show.de.txt Thu Jul 10 01:02:43 2014 +0200 231.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 231.3 @@ -1,12 +0,0 @@ 231.4 -=Initiative, Unterstützung, Anregungen= 231.5 -Während der Diskussionsphase kannst du diese Initiative unterstützen und gibst damit den Initiatoren eine wichtige Rückmeldung, inwieweit der aktuelle Entwurf auf Zustimmung stößt. Darüber hinaus kannst du durch Anregungen (Änderungsvorschläge) mitteilen, was noch verbessert werden kann bzw. unter welchen Bedingungen du dir eine Unterstützung vorstellen kannst. 231.6 - 231.7 -Du kannst dich den Anregungen anderer Mitglieder anschließen (und damit das Gewicht dieser Anregungen erhöhen) und eigene (zusätzliche) Anregungen einbringen. Anregungen, die aus deiner Sicht unbedingt eingearbeitet werden müssen, damit du zustimmst, kennzeichnest du mit ,,muss'', wünschenswerte mit ,,soll''. Du kannst Anregungen auch kritisch gegenüber stehen und sie mit ,,soll nicht'' kennzeichnen. Eine Anregung, die bei Umsetzung zum Entzug deiner Zustimmung führen würde, kennzeichnest du mit ,,darf nicht''. 231.8 -=überarbeiteter Entwurf, Umsetzungsvermerk= 231.9 -Anhand der (klassifizierten und quantifizierten) Anregungen entscheiden die Initiatoren, was sie in einem neuen Entwurf besser darstellen, ergänzen oder ändern. Der geänderte Entwurf wird den Unterstützern zur Bestätigung vorgelegt. Unterstützer können Anregungen als umgesetzt markieren, wenn die Anregung aus ihrer Sicht (hinreichend) umgesetzt wurde. Die einzelnen Unterstützer können diese Frage durchaus unterschiedlich beurteilen. 231.10 -=weitere Initiatoren einladen, Zurückziehen einer Initiative= 231.11 -Ein Initiator kann weitere Initiatoren einladen und verleiht ihnen damit gleiche Rechte für die Bearbeitung des Entwurfs. Jeder Initiator einer Initiative kann die Initiative zurückziehen und auf Wunsch den Unterstützern eine andere Initiative als Alternative empfehlen. 231.12 -=wenn du nicht gehört wirst= 231.13 -Wenn die Initiatoren deine Anregungen aus für dich nicht nachvollziehbaren Gründen nicht berücksichtigen, kannst du natürlich jederzeit eine eigene Initiative starten. 231.14 -=wenn du diese Initiative ablehnst= 231.15 -Wenn du diese Initiative grundsätzlich ablehnst, solltest du auf dieser Seite gar nichts machen, sondern die Initiative(n), der/denen du positiv gegenüber stehst, unterstützen und/oder deine eigene Initiative zu diesem Thema starten. Sofern du nicht ohnehin schon Mitglied des Themenbereichs bist, kannst du durch eine Mitgliedschaft im Themenbereich oder durch Anmeldung von Interesse am Thema die den erforderlichen Unterstützerquorum zugrundeliegende Grundgesamtheit erhöhen. Den gleichen Effekt erreichst du auch, wenn du an ein Mitglied des Themenbereichs oder einen Interessenten am Thema delegierst. **Nur bei Status ,,Neu'':** Falls das Thema, zu dem diese Initiative gehört, noch im Zustand ,,Neu'' ist und du dieses Thema eigentlich gar nicht diskutieren möchtest, solltest du zunächst nur Mitglied des Themenbereichs werden oder Interesse am Thema anmelden und keine Anregungen eingeben, die dich zum (potentiellen) Unterstützer machen würden. Ebenso solltest du noch keine Gegeninitiative starten, die das Thema über die Zulassungshürde heben könnte.
232.1 --- a/locale/help/initiative.show.el.txt Thu Jul 10 01:02:43 2014 +0200 232.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 232.3 @@ -1,24 +0,0 @@ 232.4 -==Πρωτοβουλία== 232.5 -Κάθε πρωτοβουλία έχει ως στόχο της την αντιμετώπιση και το κλείσιμο του θέματος στο οποίο αναφέρεται. Για να το πετύχουν αυτό, οι εισηγητές τους, παρέχουν μία ολοκληρωμένη πρόταση μέσω του <<προσχεδίου>> της πρωτοβουλίας και τις αναθεωρήσεις του, ζητούν την υποστήριξη του εκλογικού σώματος και λαμβάνουν υπόψη τους τις προτάσεις που τους γίνονται για την βελτίωση του <<προσχεδίου>>. 232.6 - 232.7 -=Υποστήριξη και προτάσεις= 232.8 -Κατά το στάδιο της συζήτησης μπορείτε να υποστηρίξετε αυτήν την πρωτοβουλία και να κάνετε γνωστό, στους εισηγητές, το επίπεδο συμφωνίας σας με το τρέχον <<προσχέδιο>>. Μπορείτε επίσης να κάνετε συγκεκριμένες προτάσεις για βελτιωτικές αλλαγές ή να υποδείξετε τους όρους και τις συνθήκες υπό τις οποίες θα μπορούσατε να υποστηρίξετε την πρωτοβουλία. 232.9 - 232.10 -Μπορείτε να ακολουθήσετε τις προτάσεις των άλλων μελών (αυξάνοντας έτσι το βάρος αυτών των προτάσεων) και να καταθέσετε δικές σας (επιπρόσθετες) προτάσεις. Μαρκάρετε τις προτάσεις που θεωρείτε πως είναι απαραίτητες από την πλευρά σας για να εγκρίνετε την πρωτοβουλία με <<οπωσδήποτε>> κι αυτές που θα ήταν καλό να υλοποιηθούν ως <<καλό θα ήταν>>. Μαρκάρετε τις προτάσεις που είστε δύσπιστοι ως <<καλύτερα όχι>> ενώ αυτές που, εάν ενσωματωθούν, θα σας οδηγήσουν να αποδοκιμάσετε την πρωτοβουλία με <<με τίποτα>>. 232.11 - 232.12 -=Αναθεωρημένο προσχέδιο και επανέγκριση= 232.13 -Με βάση τις προτάσεις και την υποστήριξη που συγκεντρώνουν, οι εισηγητές της πρωτοβουλίας αποφασίζουν τι πρέπει να παρουσιάσουν καλύτερα, τι να προσθέσουν ή τι να αλλάξουν στο προσχέδιο ώστε να τύχει ευρύτερης αποδοχής. 232.14 -Το βελτιωμένο προσχέδιο θα υποβληθεί στους υποστηρικτές της πρωτοβουλίας για επιβεβαίωση. Στη φάση αυτή θα πρέπει να χαρακτηρίσετε τις προτάσεις ως υλοποιημένες ή μη, ανάλογα με το πως κρίνεται το νέο προσχέδιο. Κάθε υποστηρικτής μπορεί να κρίνει τις αλλαγές διαφορετικά. 232.15 - 232.16 -=Πρόσκληση επιπλέον εισηγητών, ανάκληση πρωτοβουλίας= 232.17 -Οι εισηγητές μπορούν να προσκαλέσουν επιπλέον εισηγητές, δίνοντάς τους έτσι ίσα δικαιώματα στην πρωτοβουλία και στην συγγραφή του προσχεδίου. Κάθε εισηγητής μπορεί να ανακαλέσει την πρωτοβουλία, προτείνοντας στους υποστηρικτές της μία εναλλακτική. 232.18 - 232.19 -=Εάν δεν εισακουστείτε= 232.20 -Αν οι εισηγητές, για ανεξήγητους λόγους, δεν λάβουν υπόψη την πρότασή σας, μπορείτε, ασφαλώς, να ξεκινήσετε τη δική σας πρωτοβουλία ανά πάσα στιγμή. 232.21 - 232.22 -=Εάν αποδοκιμάζετε αυτή την πρωτοβουλία= 232.23 -Εάν διαφωνείτε επί της αρχής με αυτή την πρωτοβουλία, δεν πρέπει να κάνετε απολύτως τίποτα σε αυτή την σελίδα. Αντιθέτως, υποστηρίξτε πρωτοβουλίες που βλέπετε θετικά ή/και ξεκινήστε τη δική σας πρωτοβουλία για αυτό το θέμα. 232.24 - 232.25 -Αν δεν είστε ήδη μέλος αυτού το τομέα, μπορείτε να αυξήσετε το πλήθος των απαραίτητων υποστηρικτών με το να γίνετε μέλος του τομέα ή με το να δηλώσετε ενδιαφέρον για αυτό το θέμα. Μπορείτε να επιτύχετε το ίδιο με το να αναθέσετε το θέμα σε κάποιο μέλος που ήδη ενδιαφέρεται για το θέμα ή είναι μέλος του τομέα. 232.26 - 232.27 -**//Μόνο για το στάδιο <<Νέο>>://** Αν το θέμα αυτής της πρωτοβουλίας είναι ακόμη στο στάδιο <<Νέο>> και, πράγματι, δεν θέλετε ούτε να το συζητήσετε, θα έπρεπε πρώτα να γίνετε μέλος του τομέα ή να δηλώσετε το ενδιαφέρον σας για το θέμα αλλά να μην κάνετε καθόλου προτάσεις, οι οποίες θα σας χαρακτήριζαν (δυνητικό) υποστηρικτή. Επίσης, καλύτερα να μην ξεκινήσετε ακόμη (αντιμέτωπη) εναλλακτική πρωτοβουλία, γιατί θα μπορούσε να βοηθήσει το θέμα να ξεπεράσει το ελάχιστο όριο αποδοχής. 232.28 \ No newline at end of file
233.1 --- a/locale/help/initiative.show.en.txt Thu Jul 10 01:02:43 2014 +0200 233.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 233.3 @@ -1,12 +0,0 @@ 233.4 -=Initiative, support, suggestion= 233.5 -During the discussion phase you can support this initiative giving the initiators important feed-back about the approval level of the current draft. Apart from that you can communicate via suggestions (for making changes), what can still be improved, or indicate conditions under which you can imagine to give your support. 233.6 - 233.7 -You can follow suggestions of other members (thereby increasing the weight of these suggestions) and come up with your own (additional) suggestions. You can mark suggestions that you believe to be mandatory changes from your point of view, for you to approve with ,,must'', and nice-to-have ones with ,,should''. You can also be skeptical of suggestions and mark them with ,,should not''. You can mark a suggestion that, if realized, would lead you to disapprove, with ,,must not''. 233.8 -=revised draft, realization notes= 233.9 -Based on the (classified and quantified) suggestions the initiators decide what to present better, add or change in a new draft. The improved draft will be submitted to the supporters to ask for confirmation. Supporters can mark suggestions as implemented, if from their point of view the suggestions has been (sufficiently) implemented. Individual supporters can judge this quite differently. 233.10 -=invite further initiators, revoke an initiative= 233.11 -An initiator can invite further initiators thereby granting them equal rights on editing the draft. Every initiator of an initiative can revoke the initiative and recommend another alternative initiative to the supporters on request. 233.12 -=if you don't get heard= 233.13 -If the initiators, for inexplicable reasons, do not consider your suggestion, you can, of course, start your own initiative anytime. 233.14 -=if you disapprove this initiative= 233.15 -If you disapprove this initiative fundamentally, you should do nothing at all on this page, but support the initiative(s), that you are positive about, and/or start your own initiative related to this issue. If you are not already a member of the area you can increase the population of the necessary support quorum by becoming a member of the area or by adding your interest to the issue. You can achieve the same effect by delegating to a member of the area or a member interested at the issue. **Only for state ,,New'':** If the issue of this initiative is still in the state ,,New'' and, in fact, you do not want to discuss this issue at all, you should first only become a member of the area or add interest to the issue, but not give any suggestions, making you a (potential) supporter. Also, you should not yet start a counter initiative, which might raise the issue above the minimum admission level.
234.1 --- a/locale/help/initiative.show.eo.txt Thu Jul 10 01:02:43 2014 +0200 234.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 234.3 @@ -1,12 +0,0 @@ 234.4 -=Iniciato, subteno, sugestoj= 234.5 -Dum la diskutfazo vi povas subteni tiun ĉi iniciaton kaj donas per tio al la iniciintoj gravajn prijuĝajn rimarkojn, kiom da subteno la aktuala skizo ricevas. Plue vi povas komuniki per sugestoj (plibonigaj sugestoj) tion, kio povas esti plibonigota respektive laŭ kiuj kondiĉoj vi povas pripensi subtenon. 234.6 - 234.7 -Vi povas aliĝi al la sugestoj de aliaj membroj (kaj pligrandigi la signifon de tiuj ĉi sugestoj) kaj sugesti (pliajn) proprajn ideojn. Sugestojn, kiuj laŭ via vidpunkto nepre devas esti realigotaj, por ke vi konsentu, vi signas per „devas“, dezirindajn per „devus“. Vi ankaŭ povas kritike kontraŭstari sugestojn kaj signi ilin per „ne devus“. Sugestojn, kies realigo kaŭzus la revokon de via konsento, vi signas per „ne rajtas“. 234.8 -=Prilaborita skizo, realigrimarko= 234.9 -Laŭ la (klasifikitaj kaj kvantumitaj) sugestoj, la iniciintoj decidas, kion en nova skizo ili prezentas pli bone, aldonas aŭ ŝanĝas. Oni antaŭmetas la ŝanĝitan skizon al la subtenantoj por aprobi. Subtenantoj povas signi sugestojn kiel realigitajn, se la sugestoj laŭ ilia vidpunkto (sufiĉe) realiĝis. La individuaj subtenantoj povas juĝi tiun demandon tute diference. 234.10 -=Inviti pliajn iniciontojn, nuligi iniciaton= 234.11 -Iniciinto povas inviti pliajn iniciontojn kaj donas per tio al ili samajn rajtojn por la prilaboro de la skizo. Ĉiu iniciinto povas nuligi la iniciaton kaj laŭdezire rekomendi alian iniciaton al la subtenintoj. 234.12 -=Se vi ne estas aŭdita= 234.13 -Se la iniciintoj ne konsideras viajn sugestojn laŭ por vi neakcepteblaj kialoj, vi povas memkompreneble ĉiumomente komenci propran iniciaton. 234.14 -=Se vi malkonsentas kun tiu ĉi iniciato= 234.15 -Se vi entute malkonsentas kun tiu ĉi iniciato, vi faru nenion en tiu ĉi paĝo, sed subtenu iniciato(j)n, kun kiu(j) vi konsentas, aŭ komencu propran iniciaton pri tiu ĉi temo. Se vi ne sen tio jam estas membro de la temaro, vi povas pligrandigi la taksobazon de la atingebla kvorumo de subtenantoj per membreco en la temaro aŭ per anonco de intereso pri la temo. Vi atingas la saman efekton, se vi delegas al membro de la temaro aŭ al interesato pri la temo. **Nur ĉe stato „nova“:** Se la temo, al kiu apartenas la iniciato, ankoraŭ estas en la stato „nova“ kaj vi efektive ne ŝatus diskuti la temon, vi unue nur membriĝu ĉe la temaro aŭ anoncu intereson kaj ne enmetu sugestojn, kiuj farus vin (ebla) subtenanto. Same vi ne komencu kontraŭiniciaton, kiu povus puŝi la temon trans la kvorumon.
235.1 --- a/locale/help/initiative.show.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 235.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 235.3 @@ -1,12 +0,0 @@ 235.4 -=提案、支持、建议= 235.5 -在讨论期您可藉由提供发起者关于您对提案接受程度的重要回馈来支持提案。除了建议可改进处,您可指出您可能给予此提案支持的特定条件。 235.6 - 235.7 -您可遵循其他成员的建议(并增加这些建议的份量),并加入您自己额外的建议。在您观点中,您相信是为必须的改变,可标示为「必须」;您相信是为好的建议,可标示为「应当」;您有所质疑的建议,可标示为「不应」;您在理解后所不赞同的建议,可标示为「不可」。 235.8 -=已修改草案、更新注记= 235.9 -根据(已分类并量化的)建议,发起者决定发表更好的、新增或更改一份新的草案。改进过的草案将被送给支持者以请求确认。若支持者认为这些建议已经被充分地采纳,他们可将这些建议标示为被采纳。个别支持者对此的判断可能有极大差异。 235.10 -=邀请更多发起者、撤销提案= 235.11 -发起者可邀请更多发起者,给予他们同等的权限来编辑草案。每个发起者可撤销此提案并应要求推荐另一个替代的提案给支持者。 235.12 -=若您的意见未被采纳= 235.13 -若发起者不知原因地不考虑您的建议,您当然可在任何时候发起您自己的提案。 235.14 -=若您不赞同此提案= 235.15 -若您根本不赞同此提案,请勿在此页面做任何动作。请去支持您所肯定的提案,并/或发起您自己与此议题相关的提案。若您并非此领域的成员,您可成为此领域的成员或关心此议题以提高此提案的必备支持门槛。你可委任给一个领域成员或一个关心此议题的成员以达到同样效果。 **只在「递交期」的状态:** 若此提案的议题仍在「递交期」的状态,并且您实际上一点也不想讨论此议题,您应先成员此领域成员或关心此议题,但不给予任何建议,而成为一个(可能的)支持者。再者,您不应发起一个相对的提案,因为如此可能将此议题提升过最低递交层级。 235.16 \ No newline at end of file
236.1 --- a/locale/help/initiative.show.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 236.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 236.3 @@ -1,12 +0,0 @@ 236.4 -=提案、支持、建議= 236.5 -在討論期您可藉由提供發起者關於您對提案接受程度的重要回饋來支持提案。除了建議可改進處,您可指出您可能給予此提案支持的特定條件。 236.6 - 236.7 -您可遵循其他成員的建議(並增加這些建議的份量),並加入您自己額外的建議。在您觀點中,您相信是為必須的改變,可標示為「必須」;您相信是為好的建議,可標示為「應當」;您有所質疑的建議,可標示為「不應」;您在理解後所不贊同的建議,可標示為「不可」。 236.8 -=已修改草案、更新註記= 236.9 -根據(已分類並量化的)建議,發起者決定發表更好的、新增或更改一份新的草案。改進過的草案將被送給支持者以請求確認。若支持者認為這些建議已經被充分地採納,他們可將這些建議標示為被採納。個別支持者對此的判斷可能有極大差異。 236.10 -=邀請更多發起者、撤銷提案= 236.11 -發起者可邀請更多發起者,給予他們同等的權限來編輯草案。每個發起者可撤銷此提案並應要求推薦另一個替代的提案給支持者。 236.12 -=若您的意見未被採納= 236.13 -若發起者不知原因地不考慮您的建議,您當然可在任何時候發起您自己的提案。 236.14 -=若您不贊同此提案= 236.15 -若您根本不贊同此提案,請勿在此頁面做任何動作。請去支持您所肯定的提案,並/或發起您自己與此議題相關的提案。若您並非此領域的成員,您可成為此領域的成員或關心此議題以提高此提案的必備支持門檻。你可委任給一個領域成員或一個關心此議題的成員以達到同樣效果。**只在「遞交期」的狀態:** 若此提案的議題仍在「遞交期」的狀態,並且您實際上一點也不想討論此議題,您應先成員此領域成員或關心此議題,但不給予任何建議,而成為一個(可能的)支持者。再者,您不應發起一個相對的提案,因為如此可能將此議題提升過最低遞交層級。
237.1 --- a/locale/help/issue.show.de.txt Thu Jul 10 01:02:43 2014 +0200 237.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 237.3 @@ -1,11 +0,0 @@ 237.4 -= Thema = 237.5 - 237.6 -Auf dieser Seite werden alle Initiativen zu diesem Thema aufgelistet. Durch Klicken auf ,,Mein Interesse anmelden'' wird man für dieses Thema den Teilnehmern des übergeordneten Themenbereichs gleichgestellt, wodurch man zur Grundgesamtheit der Diskussionsteilnehmer gezählt wird, was sich auf das von Initiativen zu erreichende Unterstützerquorum auswirkt. 237.7 - 237.8 -Angemeldetes Interesse am Thema ist Voraussetzung dafür, dass eine Initiative des Themas direkt unterstützt wird, oder eigene Anregungen gegeben werden. Bei angemeldetem Interesse kommen ausgehende Delegationen für dieses Thema bis zum Abschluss der Phase ,,Eingefroren'' nicht zum tragen. Sobald man eine Initiative des Themas (direkt, nicht durch Delegation) unterstützt, wird das Interesse automatisch angemeldet. Das Zurückziehen des angemeldeten Interesses, entzieht auch die direkten Unterstützerstimmen für Initiativen dieses Themas und aktiviert ggf. ausgesetzte Delegationen. 237.9 - 237.10 -Themen durchlaufen die Phasen ,,Neu'', ,,Diskussion'', ,,Eingefroren'', ,,Abstimmung'' und ,,Abgeschlossen'', außer sie gehen bei mangelnden Unterstützerzahlen in den Zustand ,,Abgebrochen'' über. 237.11 - 237.12 -Während der Phasen ,,Neu'' und ,,Diskussion'' sollte man **allen** Initiativen, die man grundsätzlich (oder unter bestimmten Bedingungen) für zustimmungsfähig hält, unterstützen und Anregungen zur Verbesserung geben (Näheres dazu findest du auf der Initiativenseite). Hierdurch gibt man den Initiatoren die Chance, den Entwurf zu verbessern. Während dieser Phase hast man auch die Möglichkeit, eine eigene (konkurrierende) Initiative zu diesem Thema zu starten und um Unterstützung zu ringen. 237.13 - 237.14 -Initiativen des Themas, die ein bestimmtes Quorum erreichen, werden in die Endabstimmung übernommen. Die Unterstützung für eine Initiative während der Phasen ,,Neu'', ,,Diskussion'' und ,,Eingefroren'' bedeutet keine Festlegung auf das Verhalten in der Endabstimmung.
238.1 --- a/locale/help/issue.show.el.txt Thu Jul 10 01:02:43 2014 +0200 238.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 238.3 @@ -1,21 +0,0 @@ 238.4 -==Θέμα== 238.5 -Κάθε θέμα έχει μία ή παραπάνω <<πρωτοβουλίες>> τις οποίες καλείστε να υποστηρίξετε, να βελτιώσετε με τις προτάσεις σας και να ψηφίσετε. 238.6 - 238.7 -Δηλώνοντας το ενδιαφέρον σας για το θέμα αυξάνετε την βάση αξιολόγησης για την επίτευξη απαρτίας που απαιτείται για κάθε πρωτοβουλία. Το ενδιαφέρον σας για το θέμα θα δηλωθεί αυτόματα εάν υποστηρίξετε μια πρωτοβουλία για αυτό, αλλά δεν θα αφαιρεθεί παρά μόνο αν το επιλέξετε ρητά. 238.8 - 238.9 -=Ανάθεση= 238.10 -Μπορείτε να αναθέσετε το θέμα σε κάποιο άλλο μέλος από τις επαφές σας. Ανάθεση για το θέμα αυτό υπερισχύει πιθανής ανάθεσης για ολόκληρο τομέα ή ενότητα. Επίσης, πιθανή εντολή αυτόματης απόρριψης ισχύει μόνο στην περίπτωση που δεν συμμετάσχετε ο ίδιος στο τελικό στάδιο ψηφοφορίας και δεν γίνει εφαρμογή της ανάθεσης. 238.11 - 238.12 -Εάν έχετε δηλώσει ενδιαφέρον για το θέμα, πιθανή εξερχόμενη ανάθεση σας θα ανασταλεί κατά τη διάρκεια του σταδίου συζήτησης αλλά θα είναι ενεργή κατά στην τελική ψηφοφορία. 238.13 - 238.14 -=Συζήτηση= 238.15 -Κατά το στάδιο συζήτησης (κατάσταση <<Νέο>> και <<Συζήτηση>>) είναι σημαντικό **να υποστηρίξετε όλες τις πρωτοβουλίες** οι οποίες σας βρίσκουν γενικά σύμφωνους (ή υπό ορισμένες προϋποθέσεις) και να κάνετε προτάσεις για βελτιώσεις. Μ' αυτό τον τρόπο δίνετε στους εισηγητές την ευκαιρία να βελτιώσουν το προσχέδιο συμπεριλαμβάνοντας τις προτάσεις σας. 238.16 - 238.17 -Σε αυτή τη φάση σας δίνεται επίσης η δυνατότητα να ξεκινήσετε την δική σας (ανταγωνιστική) πρωτοβουλία για το θέμα και να ζητήσετε από τα μέλη να την υποστηρίξουν. 238.18 - 238.19 -=Ψηφοφορία= 238.20 -Θέματα που συμπληρώνουν την ορισμένη (από τον ισχύοντα κανονισμό) απαρτία, πηγαίνουν στο στάδιο της ψηφοφορίας. Εκεί μπορείτε να βάλετε τις πρωτοβουλίες που εγκρίνετε σε σειρά προτίμησης, ενώ για άλλες μπορείτε να απέχετε. Τέλος, μπορείτε να βάλετε με σειρά προτίμησης κι αυτές με τις οποίες διαφωνείτε. 238.21 - 238.22 -**//Σημαντικό//:** Δεν υπάρχει λόγος να προτιμήσετε μια πρόταση που θεωρείτε κατώτερη άλλης, φοβούμενοι ότι θα <<χαθεί>> η ψήφος σας εξαιτίας προβλεπόμενης πλειοψηφίας μιας άλλης. Για να το θέσουμε απλά, το σύστημα ψηφοφορίας λαμβάνει πλήρως υπόψη του τις προτιμήσεις σας ώστε όταν η πρώτη σας προτίμηση δεν έχει πιθανότητες, η ψήφος σας μετριέται εξ' ολοκλήρου προς την πρώτη σας εναλλακτική, μετά στην δεύτερη, κ.ο.κ. 238.23 - 238.24 -Για πληροφορίες σχετικά με την εκλογική διαδικασία που χρησιμοποιείται δείτε: [https://en.wikipedia.org/wiki/Schulze_method]
239.1 --- a/locale/help/issue.show.en.txt Thu Jul 10 01:02:43 2014 +0200 239.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 239.3 @@ -1,11 +0,0 @@ 239.4 -= Issue = 239.5 - 239.6 -This page lists all initiatives belonging to this issue. If you click on ""Add my interest"", you will be treated as equal to the members of the superior areas of this issue, which means that you count for the basic population for discussion in this issue. This has an impact on the supporter quorum, which initiatives have to reach. 239.7 - 239.8 -Declared interest is required to be able to directly support initiatives in this issue or to propose suggestions. As long as you are marked as interested in this issue, your outgoing delegations are postponed until the phases ""new"", ""discussion"" and ""frozen"" are finished and the issue is in voting. As soon as you support an initiative of this issue, your interest will be automatically added. Removing your interest also removes all direct support for initiatives of this issues and re-activates a previously postponed delegation. 239.9 - 239.10 -Issues run through the phases ""new"", ""discussion"", ""frozen"", ""voting"", and ""finished"", except when they are canceled beforehand due to lack of supporters of initiatives. 239.11 - 239.12 -During the phases ""new"" and ""discussion"" you should support **all** initiatives that you can agree with generally (or under certain conditions), and make suggestions for improvements (you can find details on the initiative page). Hereby you give the initiators the chance to improve the draft. During this phase you can also start your own (competing) initiative for this issue and ask people to support it. 239.13 - 239.14 -Initiatives reaching a certain quorum, will be taken into the final voting. Support of an initiative during the phases ""new"", ""discussion"" and ""frozen"" does not imply the same decision during final voting.
240.1 --- a/locale/help/issue.show.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 240.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 240.3 @@ -1,11 +0,0 @@ 240.4 -= 议题 = 240.5 - 240.6 -此页面列出所有属于此议题的提案。若您点击「关心此议题」,您将被与其他此议题上层领域的其他成员同等对待,代表您被计入讨论此议题的基本人数。这将影响提案所需达到的支持者门槛。 240.7 - 240.8 -您必须先关心此议题才可直接支持此议题中的提案或提出建议。只要您关心此议题,您所送出的委任将延后至「递交期」、「讨论期」、「底定期」都结束而此议题已开始表决之时。只要您支持此议题中的一个提案,您将自动关心此议题。移除对此议题的关心也将移除对此议题所有提案的直接支持,并重新启用之前所送出的委任。 240.9 - 240.10 -议题会经历下列阶段:「递交期」、「讨论期」、「底定期」、「表决期」以及「已结束」,除非他们因为提案缺乏支持者而提早被取消。 240.11 - 240.12 -在「递交期」及「讨论期」您应支持**所有**您大致上同意的提案(您可在提案页面上找到细节)。借此您给发起者机会去改进草案。在这时期您也可为此议题发起您自己(相竞争的)提案并请人们去支持。 240.13 - 240.14 -达特定门槛的提案将被列入最终表决。在「递交期」、「讨论期」及「底定期」支持一个提案不代表在最终表决时持相同决定。 240.15 \ No newline at end of file
241.1 --- a/locale/help/issue.show.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 241.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 241.3 @@ -1,11 +0,0 @@ 241.4 -= 議題 = 241.5 - 241.6 -此頁面列出所有屬於此議題的提案。若您點擊「關心此議題」,您將被與其他此議題上層領域的其他成員同等對待,代表您被計入討論此議題的基本人數。這將影響提案所需達到的支持者門檻。 241.7 - 241.8 -您必須先關心此議題才可直接支持此議題中的提案或提出建議。只要您關心此議題,您所送出的委任將延後至「遞交期」、「討論期」、「底定期」都結束而此議題已開始表決之時。只要您支持此議題中的一個提案,您將自動關心此議題。移除對此議題的關心也將移除對此議題所有提案的直接支持,並重新啓用之前所送出的委任。 241.9 - 241.10 -議題會經歷下列階段:「遞交期」、「討論期」、「底定期」、「表決期」以及「已結束」,除非他們因為提案缺乏支持者而提早被取消。 241.11 - 241.12 -在「遞交期」及「討論期」您應支持**所有**您大致上同意的提案(您可在提案頁面上找到細節)。 藉此您給發起者機會去改進草案。在這時期您也可為此議題發起您自己(相競爭的)提案並請人們去支持。 241.13 - 241.14 -達特定門檻的提案將被列入最終表決。在「遞交期」、「討論期」及「底定期」支持一個提案不代表在最終表決時持相同決定。
242.1 --- a/locale/help/member.edit.de.txt Thu Jul 10 01:02:43 2014 +0200 242.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 242.3 @@ -1,5 +0,0 @@ 242.4 -= Profil = 242.5 - 242.6 -Alle Angaben sind freiwillig. Im Profil erscheinen nur die Felder, die nicht leer sind. 242.7 - 242.8 -Screen-Name, Anmeldename sowie das Kennwort lassen sich im Benutzermenü unter Einstellungen ändern.
243.1 --- a/locale/help/member.edit.el.txt Thu Jul 10 01:02:43 2014 +0200 243.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 243.3 @@ -1,4 +0,0 @@ 243.4 -=Προφίλ= 243.5 -Όλες οι πληροφορίες συμπληρώνονται εθελοντικά. Μόνο μη κενά πεδία θα εμφανίζονται στο προφίλ σας. 243.6 - 243.7 -Για να αλλάξετε το ψευδώνυμο, το όνομα σύνδεσης ή τον κωδικό πρόσβασής σας πηγαίνετε στη σελίδα 'Επιλογές' από το μενού χρήστη πάνω δεξιά. Για να αλλάξετε την φωτογραφία και την εικόνα σας επιλέξτε 'Ανέβασμα εικόνων'.
244.1 --- a/locale/help/member.edit.en.txt Thu Jul 10 01:02:43 2014 +0200 244.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 244.3 @@ -1,5 +0,0 @@ 244.4 -= Profile = 244.5 - 244.6 -All information entered here is voluntary. Only non-empty fields will be shown in your profile. 244.7 - 244.8 -You can change your name, login name and password in your user menu at the upper right corner under ""settings"".
245.1 --- a/locale/help/member.edit.eo.txt Thu Jul 10 01:02:43 2014 +0200 245.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 245.3 @@ -1,5 +0,0 @@ 245.4 -= Profilo = 245.5 - 245.6 -Ĉiuj deklaroj estas libervolaj. En via profilo nur tiuj kampoj, kiuj ne estas malplenaj, estas videblaj. 245.7 - 245.8 -You can change your name, login name and password in your user menu at the upper right corner under ""settings"".
246.1 --- a/locale/help/member.edit.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 246.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 246.3 @@ -1,5 +0,0 @@ 246.4 -= 个人简介 = 246.5 - 246.6 -所有在此的资讯都是自愿输入的。只有非空白内容会被显示在您的个人简介。 246.7 - 246.8 -您可在右上角「设定」的使用者选单中改变您的使用者代号、帐号以及密码。 246.9 \ No newline at end of file
247.1 --- a/locale/help/member.edit.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 247.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 247.3 @@ -1,5 +0,0 @@ 247.4 -= 個人簡介 = 247.5 - 247.6 -所有在此的資訊都是自願輸入的。只有非空白內容會被顯示在您的個人簡介。 247.7 - 247.8 -您可在右上角「設定」的使用者選單中改變您的使用者代號、帳號以及密碼。
248.1 --- a/locale/help/member.edit_images.de.txt Thu Jul 10 01:02:43 2014 +0200 248.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 248.3 @@ -1,6 +0,0 @@ 248.4 -= Bilder = 248.5 - 248.6 -Format: JPG 248.7 -Avatar: max. 48 x 48 Pixel, für den Avatar bevorzugt ein quadratisches Bild 248.8 -Foto: max. 250 x 250 Pixel 248.9 -Größere Bilder werden herunterskaliert, alle Bilder werden recodiert und von Profilen befreit.
249.1 --- a/locale/help/member.edit_images.el.txt Thu Jul 10 01:02:43 2014 +0200 249.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 249.3 @@ -1,6 +0,0 @@ 249.4 -=Εικόνες= 249.5 -Μορφή: JPG 249.6 -Εικόνα (Avatar): μεγ. 48 x 48 pixels, μια τετράγωνη εικόνα κατά προτίμηση. 249.7 -Φωτογραφία: μεγ. 250 x 250 pixels 249.8 - 249.9 -Μεγαλύτερες εικόνες θα σμικρυνθούν. Όλες οι εικόνες θα επανακωδικοποιηθούν και τα δεδομένα προφίλ τους θα αφαιρεθούν.
250.1 --- a/locale/help/member.edit_images.en.txt Thu Jul 10 01:02:43 2014 +0200 250.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 250.3 @@ -1,6 +0,0 @@ 250.4 -= Images = 250.5 - 250.6 -Format: JPG 250.7 -Avatar: max. 48 x 48 pixels, an image in square format is preferred for your avatar 250.8 -Picture: max. 250 x 250 pixels 250.9 -Larger images will be scaled down, all images will be recoded and profile data be removed.
251.1 --- a/locale/help/member.edit_images.eo.txt Thu Jul 10 01:02:43 2014 +0200 251.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 251.3 @@ -1,6 +0,0 @@ 251.4 -= Bildoj = 251.5 - 251.6 -Formato: JPG 251.7 -Avataro: maksimume 48 × 48 rastrumeroj, por la avataro prefereble kvadrata bildo 251.8 -Foto: maksimume 250 × 250 rastrumeroj 251.9 -Pli grandaj bildoj reduktiĝas; ĉiuj bildoj rekodiĝas kaj liberiĝas de profiloj.
252.1 --- a/locale/help/member.edit_images.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 252.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 252.3 @@ -1,6 +0,0 @@ 252.4 -= 图片 = 252.5 - 252.6 -格式:JPG 252.7 -头像:最大 48 x 48 画素,一张横式的图片较适合做为您的头像。 252.8 -照片: 最大 250 x 250 画素 252.9 -更大的图片会被缩小,所有的图片将被重新编码,而图片附属资讯将被去除。 252.10 \ No newline at end of file
253.1 --- a/locale/help/member.edit_images.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 253.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 253.3 @@ -1,6 +0,0 @@ 253.4 -= 圖片 = 253.5 - 253.6 -格式:JPG 253.7 -頭像:最大 48 x 48 畫素,一張橫式的圖片較適合做為您的頭像。 253.8 -照片: 最大 250 x 250 畫素 253.9 -更大的圖片會被縮小,所有的圖片將被重新編碼,而圖片附屬資訊將被去除。
254.1 --- a/locale/help/member.settings.email_address.de.txt Thu Jul 10 01:02:43 2014 +0200 254.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 254.3 @@ -1,1 +0,0 @@ 254.4 -Diese E-Mail-Adresse kann für automatische Nachrichten des Systems sowie für die Kontaktaufnahme durch die Administratoren verwendet werden und wird anderen Benutzern nicht angezeigt. Wenn Du die Adresse änderst, erhältst Du eine E-Mail mit einem Bestätigungslink, den du anklicken musst.
255.1 --- a/locale/help/member.settings.email_address.el.txt Thu Jul 10 01:02:43 2014 +0200 255.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 255.3 @@ -1,1 +0,0 @@ 255.4 -Αυτή η διεύθυνση email μπορεί να χρησιμοποιηθεί για αυτοματοποιημένα μηνύματα από το σύστημα ή για επικοινωνία από τους διαχειριστές του συστήματος. Δεν εμφανίζεται σε άλλους χρήστες. Αν αλλάξετε αυτή την διεύθυνση θα λάβετε ένα μήνυμα επιβεβαίωσης της νέας διεύθυνσης με έναν σύνδεσμο που πρέπει να ακολουθήσετε. 255.5 \ No newline at end of file
256.1 --- a/locale/help/member.settings.email_address.en.txt Thu Jul 10 01:02:43 2014 +0200 256.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 256.3 @@ -1,1 +0,0 @@ 256.4 -This e-mail address can be used for automatic messages from the system as well as for approach by the administrators of the system. It is not displayed to other users. If you change this address, you receive an e-mail with a verification link, which you have to follow.
257.1 --- a/locale/help/member.settings.email_address.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 257.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 257.3 @@ -1,1 +0,0 @@ 257.4 -此电邮地址可被系统用来发送自动讯息,或被系统管理员用来联络您。此电邮地址将不公开显示。若您更改此地址,您会收到一封有认证连结的电邮,您必须遵循上面的指示。 257.5 \ No newline at end of file
258.1 --- a/locale/help/member.settings.email_address.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 258.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 258.3 @@ -1,1 +0,0 @@ 258.4 -此電郵地址可被系統用來發送自動訊息,或被系統管理員用來聯絡您。此電郵地址將不公開顯示。若您更改此地址,您會收到一封有認證連結的電郵,您必須遵循上面的指示。
259.1 --- a/locale/help/member.settings.login.de.txt Thu Jul 10 01:02:43 2014 +0200 259.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 259.3 @@ -1,1 +0,0 @@ 259.4 -Bitte wähle einen Anmeldenamen. Dieser wird anderen nicht gezeigt und nur von Dir zum Anmelden verwendet. Groß- und Kleinschreibung wird berücksichtigt. 259.5 \ No newline at end of file
260.1 --- a/locale/help/member.settings.login.el.txt Thu Jul 10 01:02:43 2014 +0200 260.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 260.3 @@ -1,1 +0,0 @@ 260.4 -Παρακαλώ επιλέξτε ένα όνομα σύνδεσης. Αυτό το όνομα δεν θα εμφανίζεται σε άλλους και χρησιμοποιείται μόνο για την σύνδεσή σας στο σύστημα. Προσοχή στα κεφαλαία/πεζά γράμματα, έχουν σημασία. 260.5 \ No newline at end of file
261.1 --- a/locale/help/member.settings.login.en.txt Thu Jul 10 01:02:43 2014 +0200 261.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 261.3 @@ -1,1 +0,0 @@ 261.4 -Please choose a login name. It will not be visible for other users and you will only use it for logging in. The login name is case-sensitive. 261.5 \ No newline at end of file
262.1 --- a/locale/help/member.settings.login.eo.txt Thu Jul 10 01:02:43 2014 +0200 262.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 262.3 @@ -1,1 +0,0 @@ 262.4 -Bonvolu elekti salutnomon. Tiu ne montriĝas al aliaj kaj estas uzata nur de vi por ensaluti. Uskleco estas konsiderata.
263.1 --- a/locale/help/member.settings.login.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 263.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 263.3 @@ -1,1 +0,0 @@ 263.4 -请选择一个帐号。此帐号将不会显示给其他使用者,而只由您在登入时使用。帐号的大小写是有区别的。 263.5 \ No newline at end of file
264.1 --- a/locale/help/member.settings.login.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 264.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 264.3 @@ -1,1 +0,0 @@ 264.4 -請選擇一個帳號。此帳號將不會顯示給其他使用者,而只由您在登入時使用。帳號的大小寫是有區別的。 264.5 \ No newline at end of file
265.1 --- a/locale/help/member.settings.name.de.txt Thu Jul 10 01:02:43 2014 +0200 265.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 265.3 @@ -1,1 +0,0 @@ 265.4 -Wähle einen Namen, z. B. Deinen Real- oder Nicknamen. Dieser wird anderen angezeigt um Dich zu identifizieren. Aus Gründen der Transparenz können alte Namen in Deiner Namenshistorie im Profil abgerufen werden. 265.5 \ No newline at end of file
266.1 --- a/locale/help/member.settings.name.el.txt Thu Jul 10 01:02:43 2014 +0200 266.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 266.3 @@ -1,3 +0,0 @@ 266.4 -Παρακαλώ επιλέξτε ένα όνομα, π.χ. το πραγματικό σας ή κάποιο ψευδόνυμο. Το όνομα αυτό θα εμφανίζεται στους άλλους για να σας αναγνωρίζουν. 266.5 - 266.6 -Για λόγους διαφάνειας, το ιστορικό του ονόματός σας είναι διαθέσιμο σε άλλους και φαίνεται στη σελίδα του προφίλ σας. 266.7 \ No newline at end of file
267.1 --- a/locale/help/member.settings.name.en.txt Thu Jul 10 01:02:43 2014 +0200 267.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 267.3 @@ -1,1 +0,0 @@ 267.4 -Choose a name, e.g. your real name or a nick name. This name will be visible for other users, in order to identify you. For reasons of transparency the history of your names is available for others looking at your profile. 267.5 \ No newline at end of file
268.1 --- a/locale/help/member.settings.name.eo.txt Thu Jul 10 01:02:43 2014 +0200 268.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 268.3 @@ -1,1 +0,0 @@ 268.4 -Elektu nomon, ekzemple vian veran aŭ kaŝnomon. Tiu montriĝas por identigi vin. Pro kialoj de travideblo malnovaj nomoj montriĝas en la nomhistorio de via profilo.
269.1 --- a/locale/help/member.settings.name.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 269.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 269.3 @@ -1,1 +0,0 @@ 269.4 -请选择一个使用者代号,例如您的真名或绰号。此使用者代号将会显示给其他使用者,以便辨认您。为了维持透明度,其他使用者可在您的个人简介看到您使用者代号的更改纪录。 269.5 \ No newline at end of file
270.1 --- a/locale/help/member.settings.name.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 270.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 270.3 @@ -1,1 +0,0 @@ 270.4 -請選擇一個使用者代號,例如您的真名或綽號。此使用者代號將會顯示給其他使用者,以便辨認您。為了維持透明度,其他使用者可在您的個人簡介看到您使用者代號的更改紀錄。 270.5 \ No newline at end of file
271.1 --- a/locale/help/member.settings.notification.de.txt Thu Jul 10 01:02:43 2014 +0200 271.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 271.3 @@ -1,2 +0,0 @@ 271.4 -=Benachrichtigungseinstellungen= 271.5 -Hier kannst du einstellen, ob du überhaupt und wenn ja welche Benachrichtigungen du vom System per E-Mail erhalten möchtest.
272.1 --- a/locale/help/member.settings.notification.el.txt Thu Jul 10 01:02:43 2014 +0200 272.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 272.3 @@ -1,1 +0,0 @@ 272.4 -Επιλέξτε τα γεγονότα για τα οποία θέλετε να λαμβάνετε ειδοποιήσεις μέσω email. 272.5 \ No newline at end of file
273.1 --- a/locale/help/member.settings.notification.en.txt Thu Jul 10 01:02:43 2014 +0200 273.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 273.3 @@ -1,2 +0,0 @@ 273.4 -=Notification settings= 273.5 -Please choose which notifications you like to receive from the system by email. 273.6 \ No newline at end of file
274.1 --- a/locale/help/member.settings.notification.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 274.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 274.3 @@ -1,2 +0,0 @@ 274.4 -=通知设定= 274.5 -请选择您想从系统收到的电邮通知种类。 274.6 \ No newline at end of file
275.1 --- a/locale/help/member.settings.notification.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 275.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 275.3 @@ -1,2 +0,0 @@ 275.4 -=通知設定= 275.5 -請選擇您想從系統收到的電郵通知種類。 275.6 \ No newline at end of file
276.1 --- a/locale/help/member.settings.password.de.txt Thu Jul 10 01:02:43 2014 +0200 276.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 276.3 @@ -1,1 +0,0 @@ 276.4 -Dein neues Kennwort muss mindestens 8 Zeichen lang sein.
277.1 --- a/locale/help/member.settings.password.el.txt Thu Jul 10 01:02:43 2014 +0200 277.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 277.3 @@ -1,4 +0,0 @@ 277.4 -Ο νέος σας κωδικός πρέπει να έχει τουλάχιστον 8 χαρακτήρες. Δώστε προσοχή στα κεφαλαία/πεζά γράμματα, έχουν σημασία. 277.5 - 277.6 -**Προσοχή:** Μη δίνετε ποτέ τον κωδικό πρόσβασής σας σε άλλους, ακόμη κι αν ισχυρίζονται πως είναι διαχειριστές. 277.7 -
278.1 --- a/locale/help/member.settings.password.en.txt Thu Jul 10 01:02:43 2014 +0200 278.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 278.3 @@ -1,1 +0,0 @@ 278.4 -Your new password must have at least 8 characters.
279.1 --- a/locale/help/member.settings.password.eo.txt Thu Jul 10 01:02:43 2014 +0200 279.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 279.3 @@ -1,1 +0,0 @@ 279.4 -Via nova pasvorto devas esti minimume ok signojn longa.
280.1 --- a/locale/help/member.settings.password.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 280.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 280.3 @@ -1,1 +0,0 @@ 280.4 -您的新密码必须至少有 8 个符号。 280.5 \ No newline at end of file
281.1 --- a/locale/help/member.settings.password.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 281.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 281.3 @@ -1,1 +0,0 @@ 281.4 -您的新密碼必須至少有 8 個符號。 281.5 \ No newline at end of file
282.1 --- a/locale/help/member.show.de.txt Thu Jul 10 01:02:43 2014 +0200 282.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 282.3 @@ -1,9 +0,0 @@ 282.4 -=Profilseite= 282.5 -Hier kann man erfahren, 282.6 -- was dieses Mitglied über sich selbst mitteilt, 282.7 -- in welchen Themenbereichen es Mitglied ist, 282.8 -- an welchen Themen und Initiativen es sich beteiligt 282.9 -- welche Delegationen das Mitglied erhalten und erteilt und 282.10 -- welche Kontakte das Mitglied veröffentlicht hat. 282.11 -=zu den Kontakten hinzufügen= 282.12 -Hier kann man das Mitglied außerdem zur eigenen Kontaktliste hinzufügen (und es natürlich auch wieder von dieser entfernen). Bitte beachte, dass man nur an Mitglieder delegieren kann, die man auf die eigene Kontaktliste gesetzt hat.
283.1 --- a/locale/help/member.show.el.txt Thu Jul 10 01:02:43 2014 +0200 283.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 283.3 @@ -1,9 +0,0 @@ 283.4 -==Σελίδα προφίλ== 283.5 -Εδώ μπορείτε να δείτε: 283.6 -- Τι λέει αυτό το μέλος για τον εαυτό του και τα στοιχεία που επέλεξε να μοιραστεί 283.7 -- Σε ποιες ενότητες, τομείς και θέματα συμμετέχει 283.8 -- Τις αναθέσεις που έχει ορίσει και έχει δεχτεί 283.9 -- Τις επαφές του επέλεξε να δημοσιεύσει 283.10 - 283.11 -=Προσθήκη στις επαφές σας= 283.12 -Μπορείτε να αποθηκεύσετε αυτό το μέλος στις επαφές σας (και να το αφαιρέσετε πάλι, βεβαίως). Αυτό είναι απαραίτητο όταν, για παράδειγμα, θέλετε να ορίσετε το μέλος ως αντιπρόσωπό σας, αναθέτοντάς του κάποια <<ενότητα>>, <<τομέα>> ή <<θέμα>>.
284.1 --- a/locale/help/member.show.en.txt Thu Jul 10 01:02:43 2014 +0200 284.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 284.3 @@ -1,9 +0,0 @@ 284.4 -=Profile page= 284.5 -Here you can learn, 284.6 -- what this member says about him- or herself, 284.7 -- which areas he or she is a member of, 284.8 -- in which issues and initiatives he or she participates 284.9 -- which delegations the member has received and given, and 284.10 -- which contacts the member has published. 284.11 -=add to contacts= 284.12 -You can add this member to your list of contacts (and also remove him or her from it, again, of course). Please note that you can only delegate to members, who are on your list of contacts.
285.1 --- a/locale/help/member.show.eo.txt Thu Jul 10 01:02:43 2014 +0200 285.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 285.3 @@ -1,9 +0,0 @@ 285.4 -=Profilpaĝo= 285.5 -Ĉi tie vi povas ekscii, 285.6 -– kion tiu ĉi membro komunikas pri si mem, 285.7 -– de kiuj temaroj li estas membro, 285.8 -– kiujn temojn kaj iniciatojn li partoprenas, 285.9 -– kiujn delegaciojn la membro ricevas kaj donas kaj 285.10 -– kiujn kontaktojn la membro publikigis. 285.11 -=Aldoni al la kontaktoj= 285.12 -Vi povas aldoni tiun ĉi membron al via kontaktlisto (kaj kompreneble denove forigi lin de ĝi). Bonvolu atenti, ke vi povas delegi nur al membroj, kiuj estas en via kontaktlisto.
286.1 --- a/locale/help/member.show.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 286.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 286.3 @@ -1,9 +0,0 @@ 286.4 -=个人简介= 286.5 -在此您可了解: 286.6 -- 此成员对个人的描述 286.7 -- 他或她是哪些领域的成员 286.8 -- 他或她参与哪些议题或提案 286.9 -- 此成员所送出或收到的委任 286.10 -- 此成员公开的联络人 286.11 -=加入通讯录= 286.12 -您可将此成员加入您的通讯录(当然之后可再移除之)。请注意,您只可委任给在您通讯录中的成员。 286.13 \ No newline at end of file
287.1 --- a/locale/help/member.show.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 287.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 287.3 @@ -1,9 +0,0 @@ 287.4 -=個人簡介= 287.5 -在此您可瞭解: 287.6 -- 此成員對個人的描述 287.7 -- 他或她是哪些領域的成員 287.8 -- 他或她參與哪些議題或提案 287.9 -- 此成員所送出或收到的委任 287.10 -- 此成員公開的聯絡人 287.11 -=加入通訊錄= 287.12 -您可將此成員加入您的通訊錄(當然之後可再移除之)。請注意,您只可委任給在您通訊錄中的成員。
288.1 --- a/locale/help/policy.list.de.txt Thu Jul 10 01:02:43 2014 +0200 288.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 288.3 @@ -1,1 +0,0 @@ 288.4 -Die folgenden Regelwerke sind zur Zeit konfiguriert. Nicht alle Regelwerke müssen in jedem Themengebiet verfügbar sein.
289.1 --- a/locale/help/policy.list.el.txt Thu Jul 10 01:02:43 2014 +0200 289.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 289.3 @@ -1,4 +0,0 @@ 289.4 -==Κανονισμοί== 289.5 -Οι κανονισμοί καθορίζουν τη διάρκεια των σταδίων των θεμάτων και τις ποσοτικές παραμέτρους πλειοψηφίας και απαρτίας. Κάθε θέμα υπόκειται σε έναν από τους παρακάτω κανονισμούς. 289.6 - 289.7 -//Σημείωση:// Μπορεί κάποιοι κανονισμοί να μην είναι διαθέσιμοι σε όλους τους τομείς και κατ' επέκταση στα θέματα τους. 289.8 \ No newline at end of file
290.1 --- a/locale/help/policy.list.en.txt Thu Jul 10 01:02:43 2014 +0200 290.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 290.3 @@ -1,1 +0,0 @@ 290.4 -The following policies are currently configured. Not all policies are available in every subject area.
291.1 --- a/locale/help/policy.list.eo.txt Thu Jul 10 01:02:43 2014 +0200 291.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 291.3 @@ -1,1 +0,0 @@ 291.4 -La sekvontaj regularoj estas nuntempe agorditaj. Ne ĉiuj regularoj devas esti atingeblaj ĉe ĉiu temaro.
292.1 --- a/locale/help/policy.list.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 292.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 292.3 @@ -1,1 +0,0 @@ 292.4 -下列规则是目前所设定的。并非所有规则在每个主题领域都适用。 292.5 \ No newline at end of file
293.1 --- a/locale/help/policy.list.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 293.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 293.3 @@ -1,1 +0,0 @@ 293.4 -下列規則是目前所設定的。並非所有規則在每個主題領域都適用。 293.5 \ No newline at end of file
294.1 --- a/locale/help/vote.list.de.txt Thu Jul 10 01:02:43 2014 +0200 294.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 294.3 @@ -1,11 +0,0 @@ 294.4 -= Abstimmung = 294.5 - 294.6 -Zu Beginn der Abstimmung befinden sich alle Initiativen im Feld Enthaltung. Beginne am besten mit deinem Favoriten und ziehe ihn mit der Maus in das Feld Zustimmung. Danach wählst du die nächste Initiative, der du zustimmen möchtest und ziehst sie 294.7 -- in die gleiche grüne Box, falls du dieser Initiative gleichberechtigt zustimmen möchtest oder 294.8 -- zwischen die Zustimmungs- und Enthaltungsbox, falls diese Initiative dein Ersatzwunsch sein soll. 294.9 - 294.10 -Auf diese Weise fährst du fort und legst die Präferenzreihenfolge der Initiativen, denen du zustimmen möchtest fest, wobei du gleichwertige Initiativen jeweils in die gleiche Box hineinziehst. Dann legst du deine Enthaltungen und Ablehnungen fest, wobei du auch die Ablehnungen in eine Rangreihenfolge bringen kannst, falls eine der Initiativen so etwas wie das ,,kleinere Übel'' darstellen sollte. 294.11 - 294.12 -**Wichtig:** Verlasse diese Seite über die Schaltfläche ,,Stimmabgabe abschließen''. Bis zum Ende der Abstimmung kannst du deine Angaben jederzeit ändern. Es werden keine Zwischenergebnisse der Abstimmung veröffentlicht. Die Unterstützerangaben auf der Themenübersichtsseite beziehen sich auf die abgeschlossene Diskussion, beziehen sich jeweils auf die einzelne Initiative und sind nur sehr bedingt geeignet, zwischen den Initiativen zu vergleichen. Insbesondere enthalten sie keinerlei Informationen über Präferenzen. Darüber hinaus kann sich der Teilnehmerkreis von Diskussion und Abstimmung erheblich unterscheiden. 294.13 - 294.14 -**Achtung:** Auf einigen Plattformen (zum Beispiel Smartphones oder Tablet-Computern) ist das Ziehen von Initiativen mit der Maus nicht möglich. In diesem Falle können die Pfeile links neben den jeweiligen Initiativen verwendet werden.
295.1 --- a/locale/help/vote.list.el.txt Thu Jul 10 01:02:43 2014 +0200 295.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 295.3 @@ -1,13 +0,0 @@ 295.4 -==Ψηφοφορία== 295.5 -Κατά την έναρξη της ψηφοφορίας όλες οι πρωτοβουλίες θα είναι στο πλαίσιο <<Αποχή>>. Συνιστάται να ξεκινήσετε με την αγαπημένη σας και την σύρετε με το ποντίκι σας στο πλαίσιο <<Επιδοκιμασίας>>. Στη συνέχεια επιλέξτε την επόμενη πρωτοβουλία που θέλετε να εγκρίνετε και σύρετέ την είτε: 295.6 -- Στο ίδιο πράσινο κουτί, αν θέλετε να την εγκρίνετε εξίσου ή 295.7 -- Μεταξύ του πλαισίου <<Επιδοκιμασίας>> και <<Αποχής>>, αν θέλετε αυτή η πρωτοβουλία να είναι δεύτερη επιλογή σας. 295.8 - 295.9 -Συνεχίζοντας έτσι καθορίζετε τη σειρά προτίμησης των πρωτοβουλιών που θέλετε να εγκρίνετε, δηλαδή σέρνετε ίσης προτίμησης πρωτοβουλίες στο ίδιο κουτί. Στη συνέχεια, καθορίζετε αυτές που απέχετε και αυτές που αποδοκιμάζετε, πράγμα που σημαίνει ότι μπορείτε επίσης να ορίσετε τη σειρά προτίμησης για τις απορρίψεις, για την περίπτωση που μία από τις πρωτοβουλίες αντιπροσωπεύει το "μικρότερο κακό''. 295.10 - 295.11 -**Σημαντικό:** Για να φύγετε από αυτή την σελίδα πατήστε το κουμπί <<Ολοκλήρωση ψήφου>>. Μπορείτε να αλλάξετε τις ψήφους σας οποιαδήποτε στιγμή μέχρι το τέλος της ψηφοφορίας. 295.12 - 295.13 -=Αποτελέσματα κατά τη διάρκεια της ψηφοφορίας= 295.14 -Κατά τη διάρκεια της ψηφοφορίας δεν δημοσιεύονται ενδιάμεσα αποτελέσματα. Τα στοιχεία που παρουσιάζονται στη σελίδα επισκόπησης αναφέρονται μόνο στην αντίστοιχη πρωτοβουλία και είναι κατάλληλα μόνο για συγκρίσεις σε περιορισμένο βαθμό. Ειδικότερα, δεν περιέχουν καμία πληροφορία σχετικά με τις προτιμήσεις και επιπλέον η ομάδα των ατόμων που συμμετέχουν στη συζήτηση μπορεί να είναι πολύ διαφορετική από αυτούς που πραγματικά ψηφίζουν. 295.15 - 295.16 -//Σημείωση:// Σε ορισμένες πλατφόρμες (π.χ. κινητά τηλέφωνα ή υπολογιστές tablet) μπορεί να μην είναι δυνατό να σύρετε τις πρωτοβουλίες. Σε αυτές τις περιπτώσεις, χρησιμοποιήστε το πάνω και το κάτω βέλος αριστερά της κάθε πρωτοβουλίας. 295.17 \ No newline at end of file
296.1 --- a/locale/help/vote.list.en.txt Thu Jul 10 01:02:43 2014 +0200 296.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 296.3 @@ -1,11 +0,0 @@ 296.4 -= Voting = 296.5 - 296.6 -At the beginning of the voting all initiatives will be in the Abstention field. It is recommended to start with your favourite and drag it with your mouse into the Approval field. Then you select the next initiative that you want to approve and drag it either 296.7 -- into the same green box, if you want to approve it equally or 296.8 -- between the Approval and Abstention box, if you want this initiative to be your second choice. 296.9 - 296.10 -Continuing like this you define the preference list of the initiatives, that you want to approve, i.e. you drag equal initiatives into the same box. Then you specify your abstentions and disapprovals, meaning that you can also define a preference list for disapprovals, just in case one of the initiatives should represent something like a ,,minor evil''. 296.11 - 296.12 -**Important:** Leave this page via the ,,Finish voting'' button. You can change your votes anytime until the end of the voting. During the voting no interim results are published. The support data on the issue overview page refers to the single respective initiative and is only suited to a very limited extent to compare different initiatives. Especially, it contains no information whatsoever about preferences. Moreover, the group of those participating in the discussion can be very different from those who actually vote. 296.13 - 296.14 -**Notice:** On some platforms (e.g. smartphones or tablet computers) "drag and drop" via mouse is not possible. In these cases use the up and down arrows left of each initiative.
297.1 --- a/locale/help/vote.list.eo.txt Thu Jul 10 01:02:43 2014 +0200 297.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 297.3 @@ -1,8 +0,0 @@ 297.4 -=Voĉdono= 297.5 -Depende, kiujn agordojn vi elektis, ĉiuj iniciatoj troviĝas komence en la kampo „sindeteno“ aŭ en la kampo „malkonsento“. Komencu pli bone kun via favorato kaj tiru ĝin permuse en la kampon „konsento“. Poste vi elektas la sekvan iniciaton, kiun vi volas konsenti kaj tiras ĝin 297.6 -– en la saman verdan ujon, se vi ŝatus samrajte konsenti kun tiu ĉi iniciato aŭ 297.7 -– inter la konsento- kaj la sindetenujojn, se tiu ĉi iniciato estu via anstataŭa deziro. 297.8 - 297.9 -Tiamaniere, vi daŭrigas kaj decidas la prefervicon de la iniciatoj, kun kiuj vi ŝatus konsenti, ĉe kio vi tiras samrangajn iniciatojn en la saman ujon. Tiam vi decidas la sindetenojn kaj la malkonsentojn, ĉe kio vi povas meti ankaŭ la malkonsentojn en prefervicon, se unu el la iniciatoj ŝajnus „la pli malgranda malbono“. 297.10 - 297.11 -**Grave:** Forlasu tiun ĉi paĝon per la butono „fini voĉdonadon“. Ĝis la fino de la voĉdonado vi povas ĉiutempe ŝanĝi viajn deklarojn. Provizoraj rezultoj de la voĉdono ne publikiĝas. La indiko de subtenantoj rilatas al finitaj diskutoj, rilatas al la aparta iniciato kaj nur tre relative taŭgas por kompari inter iniciatoj. Precipe, ili ne enhavas informojn pri preferoj. Krome, la partoprenantaroj de diskuto kaj voĉdono povas konsiderinde malsami.
298.1 --- a/locale/help/vote.list.zh-Hans.txt Thu Jul 10 01:02:43 2014 +0200 298.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 298.3 @@ -1,12 +0,0 @@ 298.4 -= 表决 = 298.5 - 298.6 -在表决开始时所有提案都放置在弃权区。我们建议您从您最喜爱的提案开始,并以滑鼠将其拖移至赞同区。然后选择下一个您所赞同的提案并将其拖移 298.7 -- 若您对两者同样赞同,拖移至同个绿盒子内 298.8 -- 若您想将此提案成为第二选择,就拖移至赞同与弃权区间 298.9 - 298.10 - 298.11 -如此继续,您便指定了您所赞同的提案的偏好列表,也就是您将一样赞同的提案都拖移到同个盒子里。然后您指定您所要弃权或否决的提案,也就是在某个提案对您来说只是个「小恶魔」时,您也指定您所否决的提案的偏好列表。 298.12 - 298.13 -**重要:** 请藉由「完成投票」按钮离开本页面。直到表决结束您都可更改您的投票。在表决期间不会有临时结果被公开。议题概观页面所显示的支持统计资料只针对单一提案,并且对于比较不同的提案只有非常局限的用途。特别是,它并不含有任何关于偏好的资讯。再者,参与讨论的成员组成可能与实际参与表决的成员组成非常不同。 298.14 - 298.15 -**注意:** 在某些平台(例如智慧型手机或平板电脑)以滑鼠拖放是不可能的。在此状况下请使用个案左侧的上下箭头。 298.16 \ No newline at end of file
299.1 --- a/locale/help/vote.list.zh-TW.txt Thu Jul 10 01:02:43 2014 +0200 299.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 299.3 @@ -1,12 +0,0 @@ 299.4 -= 表決 = 299.5 - 299.6 -在表決開始時所有提案都放置在棄權區。我們建議您從您最喜愛的提案開始,並以滑鼠將其拖移至贊同區。然後選擇下一個您所贊同的提案並將其拖移 299.7 -- 若您對兩者同樣贊同,拖移至同個綠盒子內 299.8 -- 若您想將此提案成為第二選擇,就拖移至贊同與棄權區間 299.9 - 299.10 - 299.11 -如此繼續,您便指定了您所贊同的提案的偏好列表,也就是您將一樣贊同的提案都拖移到同個盒子裡。然後您指定您所要棄權或否決的提案,也就是在某個提案對您來說只是個「小惡魔」時,您也指定您所否決的提案的偏好列表。 299.12 - 299.13 -**重要:** 請藉由「完成投票」按鈕離開本頁面。直到表決結束您都可更改您的投票。在表決期間不會有臨時結果被公開。議題概觀頁面所顯示的支持統計資料只針對單一提案,並且對於比較不同的提案只有非常侷限的用途。特別是,它並不含有任何關於偏好的資訊。再者,參與討論的成員組成可能與實際參與表決的成員組成非常不同。 299.14 - 299.15 -**注意:** 在某些平台(例如智慧型手機或平板電腦)以滑鼠拖放是不可能的。在此狀況下請使用個案左側的上下箭頭。
300.1 --- a/locale/help/wikisyntax.en.txt Thu Jul 10 01:02:43 2014 +0200 300.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 300.3 @@ -1,6 +0,0 @@ 300.4 -==== Wiki Help ==== 300.5 - 300.6 -You can choose between this different syntaxes: 300.7 - 300.8 -[wikisyntax_rocketwiki.html RocketWiki] 300.9 -[wikisyntax_compat.html Traditional wiki syntax]
301.1 --- a/locale/help/wikisyntax_compat.en.txt Thu Jul 10 01:02:43 2014 +0200 301.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 301.3 @@ -1,31 +0,0 @@ 301.4 -<- [wikisyntax.html Wiki Help] 301.5 - 301.6 -==== Traditional Wiki-Syntax ==== 301.7 -- ++Headings++ 301.8 --- = Main Heading (H1) = 301.9 --- == Heading (H2) == 301.10 --- === Sub-Heading (H3) === 301.11 --- ==== Sub-Sub-Heading (H4) ==== 301.12 -- ++Horizontal line++ 301.13 --- --- 301.14 -- ++Unnumbered lists++ 301.15 --- * Toplevel Entry 301.16 --- ** Sub Entry 301.17 -- ++Numbered list++ 301.18 --- # Toplevel Entry 301.19 --- ## Sub Entry 301.20 -- ++Font style++ 301.21 --- {{'''bold'''}} 301.22 --- {{''italic''}} 301.23 --- {{<tag>possible tags: big, small, sup, sub, tt, nobr</tag>}} 301.24 --- {{{{no special interpretation of formatting characters}}}} 301.25 -- ++Text flow++ 301.26 --- non-breaking(_)space 301.27 --- soft(-)hypen 301.28 -- ++Dashes++ 301.29 --- En{{{--}}}Dash 301.30 --- Em{{{---}}}Dash 301.31 -- ++Line break++ 301.32 --- {{<br>}} 301.33 -- ++Links++ 301.34 --- {{[http://example.org/ link text]}}
302.1 --- a/locale/help/wikisyntax_rocketwiki.en.txt Thu Jul 10 01:02:43 2014 +0200 302.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 302.3 @@ -1,52 +0,0 @@ 302.4 -<- [wikisyntax.html Wiki Help] 302.5 - 302.6 -==== RocketWiki ==== 302.7 -- ++Headings++ 302.8 --- ==== Main Heading (H1) ==== 302.9 --- === Heading (H2) === 302.10 --- == Sub-Heading (H3) == 302.11 --- = Sub-Sub-Heading (H4) = 302.12 -- ++Horizontal line++ 302.13 --- --- 302.14 -- ++Unnumbered lists++ 302.15 --- - Toplevel Entry 302.16 --- -- Sub Entry 302.17 -- ++Numbered list++ 302.18 --- # Toplevel Entry 302.19 --- ## Sub Entry 302.20 -- ++Font style++ 302.21 --- {{**bold**}} 302.22 --- {{//italic//}} 302.23 --- {{__underlined__}} 302.24 --- {{++big++}} 302.25 --- {{%%small%%}} 302.26 --- {{||monospaced||}} 302.27 --- {{&&no line break&&}} 302.28 --- {{{{no special interpretation of formatting characters}}}} 302.29 -- ++Quotes++ 302.30 --- {{""normal english quotes""}} 302.31 --- {{"""single english quotes"""}} 302.32 --- {{,,normal german quotes''}} 302.33 --- {{,,,single german quotes'''}} 302.34 --- {{<<normal french quotes>>}} 302.35 --- {{<<<single french quotes>>>}} 302.36 -- ++Text flow++ 302.37 --- non-breaking(_)space 302.38 --- soft(-)hypen 302.39 -- ++Special characters++ 302.40 --- {{{EUR}}} sign 302.41 --- German umlauts: {{{Ae} {Oe} {Ue} {ae} {oe} {ue}}} 302.42 --- German SZ-ligature: {{{sz} or {ss}}} 302.43 --- Mid{{{.}}}dot 302.44 --- Ellipsis {{{...}}} 302.45 --- Arrows {{{->} {=>} {<->}}} etc. 302.46 --- {{{C} 2009, Registered{R}, Trademark{TM}}} 302.47 --- {{360{deg} 0{'} 0{''}}} **=>** 360{deg} 0{'} 0{''} 302.48 --- {{{1/4} + {1/2} = {3/4}}} **=>** {1/4} + {1/2} = {3/4} 302.49 --- {{10{%o} = 1%}} **=>** 10{%o} = 1% 302.50 --- {{(5 {-} 1) {x} 3 {/} 4 {=} 3}} **=>** (5 {-} 1) {x} 3 {/} 4 {=} 3 302.51 -- ++Dashes++ 302.52 --- En{{{--}}}Dash 302.53 --- Em{{{---}}}Dash 302.54 -- ++Links++ 302.55 --- {{[http://example.org/ link text]}}
303.1 --- a/locale/translations.de.lua Thu Jul 10 01:02:43 2014 +0200 303.2 +++ b/locale/translations.de.lua Thu Jul 10 01:19:48 2014 +0200 303.3 @@ -1,36 +1,61 @@ 303.4 #!/usr/bin/env lua 303.5 return { 303.6 +["#{closed_ago} ago"] = "vor #{closed_ago}"; 303.7 +["#{count} Neutral"] = "#{count} Enthaltung"; 303.8 +["#{count} No"] = "#{count} Nein"; 303.9 +["#{count} Yes, alternative choice"] = "#{count} Ja, Alternativstimme"; 303.10 +["#{count} Yes, first choice"] = "#{count} Ja, Erststimme"; 303.11 ["#{count} canceled"] = "#{count} abgebrochen"; 303.12 -["#{count} days ago"] = "vor #{count} Tagen"; 303.13 ["#{count} finished"] = "#{count} abgeschlossen"; 303.14 ["#{count} in discussion"] = "#{count} in Diskussion"; 303.15 ["#{count} in verification"] = "#{count} eingefroren"; 303.16 ["#{count} in voting"] = "#{count} in Abstimmung"; 303.17 -["#{count} more areas in this unit"] = "#{count} weitere Themengebiete in dieser Gliederung"; 303.18 +["#{count} matching issues found"] = "#{count} passende Themen gefunden"; 303.19 +["#{count} matching members found"] = "#{count} passende Mitglieder gefunden"; 303.20 +["#{count} more areas in this unit"] = "#{count} weitere Themenbereiche in dieser Gliederung"; 303.21 ["#{count} new"] = "#{count} neue"; 303.22 ["#{count} of them have an area delegation set"] = "bei #{count} davon ist eine Delegation für den Themenbereichs gesetzt"; 303.23 ["#{count} of your outgoing delegation(s) are broken"] = "#{count} deiner ausgehenden Delegationen sind kaputt"; 303.24 -["#{date} at #{time}"] = "am #{date} um #{time}"; 303.25 +["#{count} supporter"] = "#{count} Unterstützer"; 303.26 +["#{duration}"] = false; 303.27 ["#{interested_issues_to_vote_count} issue(s) you are interested in"] = "#{interested_issues_to_vote_count} Themen, die Dich interessieren"; 303.28 ["#{interval_text} [interval]"] = "#{interval_text}"; 303.29 ["#{interval_text} ago"] = "vor #{interval_text}"; 303.30 ["#{interval_text} left"] = "noch #{interval_text}"; 303.31 +["#{interval} ago"] = "vor #{interval}"; 303.32 ["#{issues_to_vote_count} issue(s)"] = "#{issues_to_vote_count} Themen"; 303.33 +["#{issue} is in voting"] = "#{issue} ist in Abstimmung"; 303.34 ["#{name}\n\n"] = "#{name}\n\n"; 303.35 ["#{number} Image(s) has been deleted"] = "Es wurde(n) #{number} Bild(er) gelöscht"; 303.36 ["#{number} Image(s) has been updated"] = "Es wurde(n) #{number} Bild(er) aktualisiert"; 303.37 +["#{percentage}%"] = false; 303.38 ["#{policy_name} ##{issue_id}"] = false; 303.39 ["#{policy} ##{id}"] = false; 303.40 -["(#{more_count} duplicates removed)"] = "(#{more_count} Duplikate entfernt)"; 303.41 +["#{result}: #{yes_count} Yes (#{yes_percent}), #{no_count} No (#{no_percent}), #{neutral_count} Abstention (#{neutral_percent})"] = "#{result}: #{yes_count} Ja (#{yes_percent}), #{no_count} Nein (#{no_percent}), #{neutral_count} Enthaltung (#{neutral_percent})"; 303.42 +["#{result}: No votes (0)"] = "#{result}: Keine Stimmen (0)"; 303.43 +["(+ #{count} potential)"] = "(+ #{count} potentielle)"; 303.44 +["(1) Admission"] = "(1) Zulassung"; 303.45 +["(1) Admission phase"] = "(1) Zulassungsphase"; 303.46 +["(2) Discussion"] = "(2) Diskussion"; 303.47 +["(2) Discussion phase"] = "(2) Diskussionsphase"; 303.48 +["(3) Verification"] = "(3) Überprüfung"; 303.49 +["(3) Verification phase"] = "(3) Überprüfungsphase"; 303.50 +["(4) Voting"] = "(4) Abstimmung"; 303.51 +["(4) Voting phase"] = "(4) Abstimmungsphase"; 303.52 +["(5) Result"] = "(5) Ergebnis"; 303.53 +["(invited)"] = "(eingeladen)"; 303.54 ["(new window)"] = "(neues Fenster)"; 303.55 -[")) == "] = false; 303.56 ["+ #{weight}"] = "+ #{weight}"; 303.57 +["+ add new organizational unit"] = "+ neue Gliederung hinzufügen"; 303.58 +["+ add new subject area"] = "neuen Themenbereich hinzufügen"; 303.59 ["+getElementById("] = false; 303.60 +["1 matching issue found"] = "1 passendes Thema gefunden"; 303.61 +["1 matching member found"] = "1 passendes Mitglied gefunden"; 303.62 +["4 phases of a decision"] = "4 Phasen einer Entscheidung"; 303.63 +["A short title (80 chars max)"] = "Ein kurzer Titel (max. 80 Zeichen)"; 303.64 ["A-Z"] = "A-Z"; 303.65 -["API Key"] = "API-Key"; 303.66 ["API key has been created"] = "API-Schlüssel wurde erzeugt"; 303.67 ["API key has been deleted"] = "API-Schlüssel wurde gelöscht"; 303.68 -["API keys"] = "API-Schlüssel"; 303.69 ["Abandon global delegation for this area"] = "Aussetzen der globale Delegation"; 303.70 ["Abandon unit and area delegations for this issue"] = "Aussetzen der Gliederungs-/Themenbereichsdelegation"; 303.71 ["Abandon unit delegation"] = "Aussetzen der Gliederungsdelegation"; 303.72 @@ -39,30 +64,22 @@ 303.73 ["Abstention"] = "Enthaltung"; 303.74 ["Abstention [many entries]"] = "Enthaltung"; 303.75 ["Abstention [single entry]"] = "Enthaltung"; 303.76 -["Accept invitation"] = "Einladung annehmen"; 303.77 ["Accepted at"] = "Angenommen am/um"; 303.78 -["Access level"] = "Berechtigung"; 303.79 -["Activate account"] = "Account aktivieren"; 303.80 +["Account history"] = "Kontoverlauf"; 303.81 ["Active?"] = "Aktiv?"; 303.82 -["Add alternative initiative to issue"] = "Alternative Initiative zum Thema hinzufügen"; 303.83 -["Add my interest"] = "Mein Interesse anmelden"; 303.84 -["Add new suggestion"] = "Neue Anregung hinzufügen"; 303.85 -["Add new unit"] = "Neue Gliederung"; 303.86 -["Add to my contacts"] = "Zu meinen Kontakten hinzufügen"; 303.87 +["Add a new competing initiative to issue"] = "Eine neue konkurrierende Initiative hinzufügen"; 303.88 +["Add a new suggestion for improvement"] = "Einen neuen Verbesserungsvorschlag"; 303.89 ["Address"] = "Anschrift"; 303.90 -["Admin"] = "Admin"; 303.91 -["Admin menu"] = "Admin Menü"; 303.92 ["Admin?"] = "Admin?"; 303.93 +["Administrative notice:"] = "Administrativer Kommentar"; 303.94 +["Admission"] = "Zulassung"; 303.95 ["Admission time"] = "Zeit für die Zulassung"; 303.96 ["Admitted"] = "zugelassen"; 303.97 -["All areas"] = "Alle Themenbereiche"; 303.98 -["All areas in my units"] = "Alle Themengebiete in meinen Gliederungen"; 303.99 -["All issues"] = "Alle Themen"; 303.100 -["All of them"] = "Alle Benachrichtigungen"; 303.101 +["All areas in my units"] = "Alle Themenbereiche in meinen Gliederungen"; 303.102 +["All fields are optional. Please enter only data which should be published."] = "Alle Felder sind optional. Bitte nur Daten eingeben, die veröffentlicht werden sollen."; 303.103 +["All initiatives failed 2nd quorum"] = "Alle Initiativen sind am 2. Quorum gescheitert"; 303.104 ["All units"] = "Alle Gliederungen"; 303.105 -["Any"] = "Alle"; 303.106 -["Any phase"] = "Alle Phasen"; 303.107 -["Any state"] = "Alle Zustände"; 303.108 +["Allowed policies"] = "Erlaubte Regelwerke"; 303.109 ["Apply global delegation for this area (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der globalen Delegation (Zur Zeit: #{delegate_name} [#{scope}])"; 303.110 ["Apply global or area delegation for this issue (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der globalen bzw. Themenbereichsdelegation (Zur Zeit: #{delegate_name} [#{scope}])"; 303.111 ["Apply unit delegation for this area (Currently: #{delegate_name} [#{scope}])"] = "Anwenden der Gliederungsdelegation (Zur Zeit: #{delegate_name} [#{scope}])"; 303.112 @@ -78,111 +95,91 @@ 303.113 ["Approval [many entries]"] = "Zustimmung"; 303.114 ["Approval [single entry]"] = "Zustimmung"; 303.115 ["Approved"] = "Angenommen"; 303.116 -["Are you sure?"] = "Sicher?"; 303.117 +["Are you aware that revoking an initiative is irrevocable?"] = "Bist du dir bewusst, dass das Zurückziehen unwiderrufbar ist?"; 303.118 ["Area"] = "Themenbereich"; 303.119 -["Area '#{name}'"] = "Themenbereich '#{name}'"; 303.120 ["Area delegation"] = "Delegation für Themenbereich"; 303.121 ["Area list of '#{unit_name}'"] = "Themenbereiche in '#{unit_name}'"; 303.122 -["Areas"] = "Themenbereiche"; 303.123 +["As long as you are interested in this issue yourself, the delegation is suspended for this issue, but it will be applied again in the voting phase unless you vote yourself."] = "Solange du selber am Thema interessiert bist, wird die Delegation für dieses Thema ausgesetzt, jedoch während der Abstimmung erneut aktiv, es sei denn du stimmst selber ab."; 303.124 +["As soon as one initiative of this issue reaches #{quorum} support, the issue will go into discussion phase."] = "Sobald eine Initiative des Themas das 1. Quorum von #{quorum} Unterstützern erreicht, geht das Thema in die Diskussionsphase über."; 303.125 ["Author"] = "Autor"; 303.126 +["Available policies"] = "Verfügbare Regelwerke"; 303.127 ["Avatar"] = "Avatar"; 303.128 ["Back"] = "Zurück"; 303.129 -["Back to initiative"] = "Zurück zur Initiative"; 303.130 -["Back to timeline"] = "Zurück zur Zeitachse"; 303.131 -["Ballot of '#{member_name}' for issue ##{issue_id}"] = "Stimmzettel von '#{member_name}' für Thema ##{issue_id}"; 303.132 +["Ballot of '#{member_name}'"] = "Stimmzettel von '#{member_name}'"; 303.133 ["Become a member"] = "Mitglied werden"; 303.134 +["Before creating a new issue, please check any existant issues before, if the topic is already in discussion."] = "Bitte vor dem Erstellen prüfen, ob ein anderes existierendes Thema passt!"; 303.135 +["Best not admitted initiative"] = "Beste nicht zugelassene Initiative"; 303.136 ["Birthday"] = "Geburtstag"; 303.137 ["Broken delegations"] = "Kaputte Delegationen"; 303.138 -["By delegation"] = "Durch Delegationen"; 303.139 ["Calculation"] = "Auszählung"; 303.140 ["Can't remove last initiator"] = "Der letzte Initiator kann nicht entfernt werden"; 303.141 ["Can't send confirmation email"] = "Bestätigungs-E-Mail kann nicht versendet werden."; 303.142 ["Cancel"] = "Abbrechen"; 303.143 ["Cancel [nullify]"] = "Aufheben"; 303.144 ["Cancel issue"] = "Thema abbrechen"; 303.145 -["Cancel issue #{id}"] = "Thema #{id} abbrechen"; 303.146 -["Cancel issue now"] = "Thema jetzt abbrechen"; 303.147 -["Cancel refuse of invitation"] = "Ablehnung der Einladung aufheben"; 303.148 -["Cancel registration"] = "Registrierung abbrechen"; 303.149 -["Canceled"] = "Abgebrochen"; 303.150 -["Canceled (before accepted due to revocation)"] = "Abgebrochen (in Neu-Phase, wegen Rückzug)"; 303.151 -["Canceled (during discussion due to revocation)"] = "Abgebrochen (während Diskussion, wegen Rückzug)"; 303.152 -["Canceled (during verification due to revocation)"] = "Abgebrochen (während Eingefroren-Phase, wegen Rückzug)"; 303.153 -["Canceled (issue not accepted)"] = "Abgebrochen (Thema nicht akzeptiert)"; 303.154 -["Canceled (no initiative admitted)"] = "Abgebrochen (Keine Initiative zugelassen)"; 303.155 +["Cancel issue ##{id}"] = "Thema ##{id} abbrechen"; 303.156 ["Canceled by administrative intervention"] = "Durch administrativen Eingriff abgebrochen"; 303.157 -["Change area delegation"] = "Delegation für Themenbereich ändern"; 303.158 -["Change email"] = "E-Mail-Adresse ändern"; 303.159 ["Change email address"] = "E-Mail-Adresse ändern"; 303.160 -["Change issue delegation"] = "Delegation für Thema ändern"; 303.161 -["Change login"] = "Login ändern"; 303.162 -["Change name"] = "Name ändern"; 303.163 -["Change notification settings"] = "Benachrichtigungseinstellungen ändern"; 303.164 ["Change order"] = "Sortierung ändern"; 303.165 -["Change password"] = "Kennwort ändern"; 303.166 -["Change unit delegation"] = "Delegation für Gliederung ändern"; 303.167 -["Change vote"] = "Abstimmung ändern"; 303.168 -["Change your login"] = "Deinen Anmeldenamen ändern"; 303.169 -["Change your notification email address"] = "Deine E-Mail-Adresse für Benachrichtigungen ändern"; 303.170 -["Change your password"] = "Dein Kennwort ändern"; 303.171 -["Change your screen name"] = "Deinen Screen-Namen ändern"; 303.172 -["Check delegations"] = "Delegationen pr\000fen"; 303.173 -["Check your delegations!"] = "Delegationen pr\000fen!"; 303.174 -["Choose initiator"] = "Initiator auswählen"; 303.175 +["Check and enter personal data"] = "Persönliche Daten prüfen und eingeben"; 303.176 +["Check your #{scope} delegation to '#{trustee_name}' for '#{context}'"] = "Delegation für #{scope} '#{context}' an '#{trustee_name}' prüfen"; 303.177 +["Check your delegations!"] = "Delegationen prüfen!"; 303.178 +["Check your outgoing delegations"] = "Ausgehende Delegation prüfen!"; 303.179 +["Choose a formatting engine:"] = "Formatierungsmethode auswählen"; 303.180 +["Choose a member to invite"] = "Wer soll eingeladen werden?"; 303.181 +["Choose an initiator to remove"] = "Wer soll entfernt werden?"; 303.182 ["Choose member"] = "Mitglied auswählen"; 303.183 +["Choose your delegatee"] = "Delegierten ausw\000hlen"; 303.184 ["Closed"] = "geschlossen"; 303.185 ["Closed issues"] = "Geschlossene Themen"; 303.186 -["Closed user group, please login to participate."] = "Geschlossene Benutzergruppe: Bitte melde dich an um teilzunehmen."; 303.187 +["Closed user group"] = "Geschlossene Benutzergruppe"; 303.188 ["Collective opinion of supporters"] = "Meinungsbild der Unterstützer"; 303.189 -["Commit suggestion"] = "Anregung speichern"; 303.190 ["Compare"] = "Vergleichen"; 303.191 +["Comparision of revisions #{id1} and #{id2}"] = "Vergleich der Revisionen #{id1} und #{id2}"; 303.192 +["Competing initiatives"] = "Konkurrierende Initiativen"; 303.193 +["Competing initiatives failed the 2nd quorum (#{num}/#{den}):"] = "Konkurrierende Initiativen, die am 2. Quorum (#{num}/#{den}) scheiterten:"; 303.194 +["Competing initiatives in pairwise comparison to best initiative:"] = "Konkurrierende Initiativen im Vergleich zur besten:"; 303.195 +["Competing initiatives in pairwise comparison to winner:"] = "Konkurrierende Initiativen im Vergleich zum Gewinner"; 303.196 ["Configure notifications now"] = "Benachrichtigungen jetzt konfigurieren"; 303.197 ["Confirm"] = "Bestätigen"; 303.198 +["Confirm notification address"] = "Benachrichtungsadresse bestätigen"; 303.199 +["Confirm your email address"] = "E-Mail-Adresse bestätigen"; 303.200 ["Confirmation code"] = "Bestätigungscode"; 303.201 ["Confirmation code invalid!"] = "Bestätigungscode ist ungültig!"; 303.202 -["Confirmed address"] = "Bestätigte E-Mail"; 303.203 ["Contacts"] = "Kontakte"; 303.204 -["Content"] = "Inhalt"; 303.205 -["Counting starts soon"] = "Auszählung beginnt in Kürze"; 303.206 -["Create / edit area"] = "Themengebiet anlegen / bearbeiten"; 303.207 -["Create / edit policy"] = "Regelwerk anlegen / bearbeiten"; 303.208 -["Create alternative initiative"] = "Alternative Initiative hinzufügen"; 303.209 +["Create a new issue"] = "Neues Thema erstellen"; 303.210 ["Create new area"] = "Neuen Themenbereich anlegen"; 303.211 -["Create new issue"] = "Neues Thema anlegen"; 303.212 ["Create new policy"] = "Neues Regelwerk anlegen"; 303.213 ["Create new unit"] = "Neue Gliederung anlegen"; 303.214 ["Created at"] = "Erzeugt am/um"; 303.215 +["Current delegatee"] = "Aktueller Delegierter"; 303.216 ["Current name"] = "Aktueller Name"; 303.217 ["Current phase is already closed."] = "Die aktuelle Phase ist schon abgeschlossen."; 303.218 ["Current status"] = "Aktueller Status"; 303.219 -["Current trustee"] = "Aktueller Delegierter"; 303.220 ["Current unit and area delegations need confirmation"] = "Aktuelle Gliederungs- und Themenbereichsdelegationen benötigen Bestätigung"; 303.221 ["Current votings in areas you are member of and issues you are interested in:"] = "Jetzt laufende Abstimmungen zu Themen aus Deinen Themenbereichen oder solchen an denen Du interessiert bist:"; 303.222 ["Currently no API key is set."] = "Zur Zeit ist kein API-Schlüssel festgelegt."; 303.223 ["Currently required"] = "Zur Zeit benötigt"; 303.224 -["Database download"] = "Datenbank herunterladen"; 303.225 +["Currently this is the only initiative in this issue, because nobody started a competing initiative (yet)."] = "Zur Zeit ist dies die einzige Initiative in diesem Thema, da (noch) keine konkurrierende Initiative gestartet wurde."; 303.226 ["Date format is not valid. Please use following format: YYYY-MM-DD"] = "Datumsformat nicht korrekt. Bitte verwende: JJJJ-MM-TT, also z.B. 1945-05-23"; 303.227 ["Default Policy"] = "Standard-Regelwerk"; 303.228 ["Degree"] = "Grad"; 303.229 -["Delegate area"] = "Themengebiet delegieren"; 303.230 +["Delegate area"] = "Themenbereich delegieren"; 303.231 ["Delegate issue"] = "Thema delegieren"; 303.232 ["Delegate unit"] = "Gliederung delegieren"; 303.233 ["Delegation abandoned"] = "Delegation ausgesetzt"; 303.234 -["Delegation turned off for area"] = "Delegation für Themengebiet ausgesetzt"; 303.235 +["Delegation turned off for area"] = "Delegation für Themenbereich ausgesetzt"; 303.236 ["Delegation turned off for issue"] = "Delegation für Thema ausgesetzt"; 303.237 ["Delegations"] = "Delegationen"; 303.238 -["Delete"] = "Löschen"; 303.239 -["Delete filter"] = "Filter löschen"; 303.240 +["Describe how the proposal and/or the reasons of the initiative could be improved"] = "Beschreibe, wie der Antrag und/oder die Begründung verbessert werden könnten"; 303.241 ["Description"] = "Beschreibung"; 303.242 ["Details"] = "Details"; 303.243 ["Developer settings"] = "Einstellungen für Entwickler"; 303.244 -["Diff"] = "Differenz"; 303.245 -["Direct"] = "Direkt"; 303.246 -["Direct and by delegation"] = "Direkt und delegiert"; 303.247 +["Did the initiator implement this suggestion?"] = "Hat der Initiatior die Anregung umgesetzt?"; 303.248 ["Direct majority"] = "Direkte Mehrheit"; 303.249 -["Direct majority denumerator"] = "Direkte Mehrheit Denumerator"; 303.250 +["Direct majority denominator"] = "Direkte Mehrheit Nenner"; 303.251 ["Direct majority non negative"] = "Direkte Mehrheit Nicht-Negative"; 303.252 -["Direct majority numerator"] = "Direkte Mehrheit Numerator"; 303.253 +["Direct majority numerator"] = "Direkte Mehrheit Zähler"; 303.254 ["Direct majority positive"] = "Direkte Mehrheit Positv"; 303.255 ["Disapproval (prefer to last block) [many entries]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)"; 303.256 ["Disapproval (prefer to last block) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber letztem Ablehnungsblock)"; 303.257 @@ -192,57 +189,71 @@ 303.258 ["Disapproval (prefer to lower blocks) [single entry]"] = "Ablehnung (jedoch Bevorzugung gegenüber unteren Ablehnungsblöcken)"; 303.259 ["Disapproval [many entries]"] = "Ablehnung"; 303.260 ["Disapproval [single entry]"] = "Ablehnung"; 303.261 -["Discard voting"] = "Abstimmung zurückziehen"; 303.262 -["Discuss with initiators"] = "Diskussion mit den Initiatoren"; 303.263 +["Disapproved"] = "Abgelehnt"; 303.264 +["Discard my vote"] = "Meine Stimme zurückziehen"; 303.265 ["Discussion"] = "Diskussion"; 303.266 +["Discussion #{time_info}"] = false; 303.267 ["Discussion URL"] = "Diskussions-URL"; 303.268 -["Discussion on issue"] = "Diskussion zum Thema"; 303.269 ["Discussion started"] = "Diskussion gestartet"; 303.270 -["Discussion starts soon"] = "Diskussion startet in Kürze"; 303.271 ["Discussion time"] = "Zeit für die Diskussion"; 303.272 -["Discussion with initiators"] = "Diskussion mit den Initiatoren"; 303.273 -["Do not vote directly"] = "Nicht selbst abstimmen"; 303.274 +["Do you want to suggest to support another initiative?"] = "Möchtest du eine andere Initiative empfehlen?"; 303.275 ["Download"] = "Download"; 303.276 ["Download database export"] = "Datenbankexport herunterladen"; 303.277 ["Download documents"] = "Dokumente herunterladen"; 303.278 -["Draft"] = "Entwurf"; 303.279 +["Draft history"] = "Entwurfshistorie"; 303.280 +["Draft revision #{id}"] = "Entwurf Revision #{id}"; 303.281 +["During the discussion phase the issue is debated between initiators while the initiatives are improved by suggestions from the supporters."] = "Während der Diskussionsphase wird das Thema zwischen den Initiatoren debattiert, während die Entwurfstext der Initiativen durch Verbesserungsvorschläge der Unterstützer weiterentwickelt wird."; 303.282 +["During the verification phase the initiative drafts cannot be changed anymore."] = "Während der Überprüfungsphase kann der Text der Initiative nicht mehr geändert werden."; 303.283 ["Edit"] = "Bearbeiten"; 303.284 +["Edit again"] = "Nochmal bearbeiten"; 303.285 ["Edit areas"] = "Themenbereiche bearbeiten"; 303.286 -["Edit draft"] = "Entwurf bearbeiten"; 303.287 ["Edit initiative"] = "Initiative bearbeiten"; 303.288 -["Edit my page"] = "Meine Seite bearbeiten"; 303.289 -["Edit my profile"] = "Mein Profil bearbeiten"; 303.290 ["Edit profile"] = "Profil bearbeiten"; 303.291 +["Edit voting comment"] = "Abstimmungskommentar bearbeiten"; 303.292 +["Edit your profile data"] = "Profildaten bearbeiten"; 303.293 ["Eligible as winner"] = "Als Gewinner qualifiziert"; 303.294 +["Eligible members (#{count})"] = "Stimmberechtigte Teilnehmer (#{count})"; 303.295 ["Eligible voters"] = "Stimmberechtigte"; 303.296 ["Email address"] = "E-Mail-Adresse"; 303.297 ["Email address confirmation"] = "Bestätigung der E-Mail-Adresse"; 303.298 +["Email address for notifications"] = "E-Mail-Adresse für Benachrichtungen"; 303.299 ["Email address is confirmed now"] = "E-Mail-Adresse ist jetzt bestätigt"; 303.300 ["Email address too short!"] = "E-Mail-Adresse ist zu kurz!"; 303.301 ["Email confirmation request"] = "Bestätigung deiner E-Mail-Adresse"; 303.302 -["Empty help text: #{id}.#{lang}.txt"] = "Leerer Hilfe-Text: #{id}.#{lang}.txt"; 303.303 +["Emphasis"] = "Hervorhebung"; 303.304 +["Enter a new email address:"] = "Neue E-Mail-Adresse eingeben:"; 303.305 +["Enter a new login name"] = "Neuen Anmeldenamen eingeben:"; 303.306 +["Enter a new password:"] = "Neues Kennwort eingeben"; 303.307 +["Enter a new screen name:"] = "Neuen Screen-Namen eingeben"; 303.308 +["Enter a title for your initiative (max. 140 chars):"] = "Einen Titel für die Iniative eingeben (max. 140 Zeichen)"; 303.309 +["Enter your current password:"] = "Bisheriges Kennwort eingeben:"; 303.310 +["Enter your new password again please:"] = "Das neue Kennwort bitte nocheinmal eingeben:"; 303.311 +["Enter your proposal and/or reasons"] = "Antrag und/oder Begründung eingeben"; 303.312 +["Enter your proposal and/or reasons:"] = "Antrag und/oder Begründung eingeben:"; 303.313 ["Error while converting image. Please note, that only JPG files are supported!"] = "Fehler beim Konvertieren des Bilds. Bitte beachte, dass nur JPG-Dateien unterstützt werden."; 303.314 ["Error while updating member, database reported:<br /><br /> (#{errormessage})"] = "Fehler beim aktualisieren des Mitglieds, die Datenbank berichtet folgenden Fehler:<br /><br /> (#{errormessage})"; 303.315 ["Etherpad authentication failed"] = "Etherpad-Anmeldung fehlgeschlagen"; 303.316 ["Event #{id} -> #{num} members"] = false; 303.317 -["Everything"] = "Alles"; 303.318 ["External memberships"] = "Externe Mitgliedschaften"; 303.319 ["External posts"] = "Externe Ämter"; 303.320 +["Failed #{sign}#{num}/#{den}"] = "Gescheitert #{sign}#{num}/#{den}"; 303.321 +["Failed 1st quorum"] = "Am 1. Quorum gescheitert"; 303.322 ["Finish delegation check"] = "Delegationsprüfung abschließen"; 303.323 ["Finish voting"] = "Stimmabgabe abschließen"; 303.324 -["Finished"] = "Abgeschlossen"; 303.325 -["Finished (with winner)"] = "Abgeschlossen (mit Gewinner)"; 303.326 -["Finished (without winner)"] = "Abgeschlossen (ohne Gewinner)"; 303.327 -["Forgot login name?"] = "Anmeldename vergessen?"; 303.328 +["Finished with winner"] = "Mit Gewinner abgeschlossen"; 303.329 +["For numbered items use a digit (e.g. 1) followed by a dot (.) and a space"] = "Für nummerierte Listen verwende eine Ziffer (e.g. 1) gefolgt von einem Punkt (.) und einem Leerschritt"; 303.330 +["For which issue phases do you like to receive notification emails?"] = "Für welche Themenphasen sollen E-Mail-Benachrichtigungen versendet werden?"; 303.331 +["Forgot login name?"] = "Anmeldenamen vergessen?"; 303.332 ["Forgot password?"] = "Kennwort vergessen?"; 303.333 -["Free timing"] = "Freie Zeitsteuerung"; 303.334 -["Friday"] = "Freitag"; 303.335 +["Formatting help"] = "Hilfe zur Formatierung"; 303.336 +["Free timing:"] = "Freie Zeitsteuerung:"; 303.337 ["Frozen"] = "Eingefroren"; 303.338 ["Fully frozen at"] = "Ganz eingefroren am/um"; 303.339 ["Generate API key"] = "API-Schlüssel erzeugen"; 303.340 ["Global delegation"] = "Globale Delegation"; 303.341 -["Global search"] = "Globale Suche"; 303.342 +["Go back to home page"] = "Zurück zur Startseite"; 303.343 ["Half frozen at"] = "Halb eingefroren am/um"; 303.344 +["Headlines"] = "Überschriften"; 303.345 ["Hello\n\n"] = "Hallo\n\n"; 303.346 ["Hello "] = "Hallo "; 303.347 ["Hello,\n\n"] = "Hallo, "; 303.348 @@ -250,85 +261,112 @@ 303.349 ["Help for: #{text}"] = "Hilfe zu: #{text}"; 303.350 ["Hide"] = "Verstecken"; 303.351 ["Hide active units"] = "Aktive units ausblenden"; 303.352 -["Hide filter details"] = "Filter-Details verstecken"; 303.353 -["Hide this help message"] = "Diesen Hilfetext ausblenden"; 303.354 ["Hint"] = "Hinweis"; 303.355 -["History"] = "Historie"; 303.356 +["History"] = "Zeitlicher Verlauf"; 303.357 ["Home"] = "Startseite"; 303.358 +["How important is your suggestions for you?"] = "Wie wichtig ist diese Anregung?"; 303.359 +["How this member voted"] = "Wie dieses Mitglied abgestimmt hat"; 303.360 ["I consider suggestion as"] = "Ich halte die Anregung für"; 303.361 -["I like to receive notifications by email about events in my areas and issues:"] = "Ich möchte per E-Mail über die folgenden Ereignisse in meinen Themenbereichen und Themen informiert werden:"; 303.362 +["I do not like to hear from this member"] = "Ich möchte nichts mehr von diesem Mitglied mitbekommen"; 303.363 +["I do not like to receive notifications by email"] = "Ich möchte keine Benachrichtigungen per E-Mail erhalten"; 303.364 +["I don't like any of the initiative in this issue and I want to add my opinion or counter proposal"] = "Ich mag keine der Initiativen in diesem Thema und möchte meine Meinung oder Gegenvorschlag einbringen"; 303.365 +["I don't like this initiative and I want to add my opinion or counter proposal"] = "Ich mag diese Initiative nicht und möchte meine Meinung oder Gegenvorschlag einbringen"; 303.366 +["I don't like to vote this issue (myself):"] = "Ich möchte für dieses Thema nicht (selber) abstimmen:"; 303.367 +["I like this initiative and I want to support it"] = "Ich mag diese Initiative und möchte sie unterstützen"; 303.368 +["I like to change/revoke my vote:"] = "Ich möchte meine Stimme ändern/widerrufen"; 303.369 +["I like to receive notifications"] = "Ich möchte Benachrichtigungen erhalten"; 303.370 +["I like to vote on this issue:"] = "Ich möchte für dieses Thema abstimmen"; 303.371 +["I understand, that this is not revocable"] = "Ich verstehe, dass dies nicht widerrufbar ist"; 303.372 +["I want to change account settings"] = "Ich möchte meine Kontoeinstellungen ändern"; 303.373 +["I want to change the interface language"] = "Ich möchte die Sprache ändern"; 303.374 +["I want to customize my profile"] = "Ich möchte mein Profil anpassen"; 303.375 +["I want to delegate my vote"] = "Ich möchte meine Stimme delegieren"; 303.376 +["I want to delegate this issue"] = "Ich möchte dieses Thema delegieren"; 303.377 +["I want to delegate this organizational unit"] = "Ich möchte diese Gliederung delegieren"; 303.378 +["I want to delegate this subject area"] = "Ich möchte diesen Themenbereich delegieren"; 303.379 +["I want to improve this initiative"] = "Ich möchte die Initiative verbessern"; 303.380 +["I want to know whats going on"] = "Ich möchte wissen was los ist"; 303.381 +["I want to learn more about LiquidFeedback"] = "Ich möchte mehr über LiquidFeedback lernen"; 303.382 +["I want to logout"] = "Ich möchte mich ausloggen"; 303.383 +["I want to manage my saved contacts"] = "Ich möchte meine gespeicherten Kontakte bearbeiten"; 303.384 +["I want to participate in this issue"] = "Ich möchte an diesem Thema teilnehmen"; 303.385 +["I want to participate in this subject area"] = "Ich möchte an diesem Themenbereich teilnehmen"; 303.386 +["I want to save this member as contact (i.e. to use as delegatee)"] = "Ich möchte dieses Mitglied als Kontakt speichern (z.B. als Delegationsempfänger)"; 303.387 +["I want to start a new initiative"] = "Ich möchte eine neue Initiative starten"; 303.388 +["I want to stay informed"] = "Ich möchte informiert bleiben"; 303.389 +["I want to take a look at other organizational units"] = "Ich möchte einen Blick auf andere Gliederungen werfen"; 303.390 +["I'm interested in this issue"] = "Ich bin an diesem Thema interessiert"; 303.391 +["I'm supporting this initiative"] = "Ich unterstütze diese Initiative"; 303.392 ["Id"] = "Id"; 303.393 ["Identification"] = "Identifikation"; 303.394 ["If this link is not working, please open following url in your web browser:\n\n"] = "Sollte der Link nicht funktionieren, öffne bitte die folgenden URL in Deinem Web-Browser:\n\n"; 303.395 -["Ignore Areas"] = "Ignoriere Bereiche"; 303.396 +["If you cannot find any appropriate existing issue, "] = "Wenn kein passendes Thema existiert, "; 303.397 ["Ignore initiative"] = "Initiative ignorieren"; 303.398 -["Ignore member"] = "Mitglied ignorieren"; 303.399 -["Images"] = "Bilder"; 303.400 ["Implicitly admitted"] = "Implizit zugelassen"; 303.401 ["Incoming delegations"] = "Eingehende Delegationen"; 303.402 +["Incoming delegations for '#{member_name}'"] = "Eingehende Delegationen für '#{member_name}'"; 303.403 +["Incoming delegations for '#{member}'"] = "Eingehende Delegationen für '#{member}'"; 303.404 +["Indent sub items with spaces"] = "Unterpunkte mit Leerschritt einrücken"; 303.405 ["Index"] = "Positionsnummer"; 303.406 ["Indirect majority"] = "Indirekte Mehrheit"; 303.407 -["Indirect majority denumerator"] = "Indirekte Mehrheit Denumerator"; 303.408 +["Indirect majority denominator"] = "Indirekte Mehrheit Nenner"; 303.409 ["Indirect majority non negative"] = "Indirekte Mehrheit Nicht-Negativ"; 303.410 -["Indirect majority numerator"] = "Indirekte Mehrheit Numerator"; 303.411 +["Indirect majority numerator"] = "Indirekte Mehrheit Zähler"; 303.412 ["Indirect majority positive"] = "Indirekte Mehrheit Positiv"; 303.413 -["Information about the available policies"] = "Informationen zu den verfügbaren Regelwerken"; 303.414 -["Initiated"] = "Initiiert"; 303.415 -["Initiative"] = "Initiative"; 303.416 -["Initiative ##{id}"] = "Initiative ##{id}"; 303.417 -["Initiative events"] = "Initiativen-Ereignisse"; 303.418 -["Initiative i#{id}: #{name}"] = "Initiative i#{id}: #{name}"; 303.419 ["Initiative is revoked now"] = "Initiative ist jetzt zurückgezogen"; 303.420 +["Initiative not admitted"] = "Initiative nicht zugelassen"; 303.421 ["Initiative quorum"] = "Quorum Initiative"; 303.422 -["Initiative quorum denumerator"] = "Initiativ-Quorum Nenner"; 303.423 +["Initiative quorum denominator"] = "Initiative-Quroum Nenner"; 303.424 ["Initiative quorum numerator"] = "Initiativ-Quorum Zähler"; 303.425 ["Initiative revoked"] = "Initiative zurückgezogen"; 303.426 ["Initiative successfully created"] = "Initiative erfolgreich erzeugt"; 303.427 ["Initiative successfully updated"] = "Initiative erfolgreich aktualisiert"; 303.428 ["Initiative: "] = "Initiative: "; 303.429 +["Initiatives"] = "Initiativen"; 303.430 +["Initiatives and issues"] = "Initiativen und Themen"; 303.431 +["Initiatives created by this member"] = "Initiativen von diesem Mitglied"; 303.432 ["Initiatives that invited you to become initiator:"] = "Initiative, die Dich eingeladen haben, Initiator zu werden:"; 303.433 ["Initiator invites"] = "Einladungen"; 303.434 ["Initiators"] = "Initiatoren"; 303.435 -["Interest not existent"] = "Interesse existiert nicht"; 303.436 +["Interest already removed"] = "Interesse wurde bereits abgemeldet"; 303.437 ["Interest removed"] = "Interesse entfernt"; 303.438 ["Interest updated"] = "Interesse aktualisiert"; 303.439 -["Interested"] = "Interessiert"; 303.440 -["Interested members"] = "Interessierte Mitglieder"; 303.441 +["Interested members"] = "Interessierte Teilnehmer"; 303.442 ["Internal posts"] = "Interne Ämter"; 303.443 ["Interval format:"] = "Intervall-Format"; 303.444 +["Introduction"] = "Einführung"; 303.445 ["Invalid login name or password!"] = "Anmeldename oder Kennwort ungültig"; 303.446 -["Invalid query"] = "Ungültige Anfrage"; 303.447 ["Invitation has been refused"] = "Einladung wurde widerrufen"; 303.448 ["Invitation to LiquidFeedback"] = "Einladung zu LiquidFeedback"; 303.449 ["Invite an initiator to initiative"] = "Initiator zur Initiative einladen"; 303.450 ["Invite code"] = "Einladungscode"; 303.451 -["Invite initiator"] = "Initiator einladen"; 303.452 +["Invite member"] = "Mitglied einladen"; 303.453 ["Invited"] = "Eingeladen"; 303.454 -["Issue"] = "Thema"; 303.455 +["Issue #"] = "Thema #"; 303.456 ["Issue ##{id}"] = "Thema ##{id}"; 303.457 -["Issue ID"] = "Thema #"; 303.458 -["Issue accepted"] = "Thema akzeptiert"; 303.459 -["Issue canceled"] = "Thema abgebrochen"; 303.460 +["Issue ##{issue_id}: #{initiative_name}"] = "Thema ##{issue_id}: #{initiative_name}"; 303.461 ["Issue delegation"] = "Issue-Delegation"; 303.462 -["Issue events"] = "Themen-Ereignisse"; 303.463 -["Issue finished"] = "Thema abgeschlossen"; 303.464 -["Issue finished without voting"] = "Thema ohne Abstimmung abgeschlossen"; 303.465 -["Issue frozen"] = "Thema eingefroren"; 303.466 ["Issue has been canceled"] = "Thema wurde abgebrochen"; 303.467 -["Issue pad"] = "Pad zum Thema"; 303.468 ["Issue quorum"] = "Quorum Thema"; 303.469 -["Issue quorum denumerator"] = "Themen-Quorum Nenner"; 303.470 +["Issue quorum denominator"] = "Themen-Quroum Nenner"; 303.471 ["Issue quorum numerator"] = "Themen-Quorum Zähler"; 303.472 ["Issue reached next phase"] = "Thema hat die nächste Phase erreicht"; 303.473 +["Issues in admission phase"] = "Themen in Zulassung"; 303.474 +["Issues in discussion phase"] = "Themen in Diskussion"; 303.475 +["Issues in verification phase"] = "Themen in Überprüfung"; 303.476 +["Issues in voting phase"] = "Themen in Abstimmung"; 303.477 ["Issues:"] = "Themen:"; 303.478 ["JavaScript is disabled or not available."] = "JavaScript ist abgeschaltet oder nicht verfügbar."; 303.479 ["Last activity (updated daily)"] = "Letzte Aktivität (täglich aktualisiert)"; 303.480 -["Last snapshot:"] = "Letzte Auszählung:"; 303.481 -["Latest draft created at #{date} #{time}"] = "Letzter Entwurf vom #{date} um #{time}"; 303.482 +["Last counting:"] = "Letzte Auszählung"; 303.483 +["Latest activity"] = "Letzte Aktivität"; 303.484 +["Latest approved issue"] = false; 303.485 +["Latest disapproved issue"] = false; 303.486 ["Latest events"] = "Letzte Ereignisse"; 303.487 -["License"] = "Lizenz"; 303.488 +["Links"] = "Links"; 303.489 ["LiquidFeedback"] = "LiquidFeedback"; 303.490 -["List all revisions (#{count})"] = "Zeige alle Versionen (#{count})"; 303.491 +["Lists"] = "Listen"; 303.492 +["Lists must be preceeded and followed by at least one blank line"] = "Listen müssen von Leerzeilen umgeben sein"; 303.493 ["Lock member?"] = "Mitglied sperren?"; 303.494 ["Locked?"] = "Gesperrt?"; 303.495 ["Login"] = "Anmeldung"; 303.496 @@ -337,117 +375,102 @@ 303.497 ["Login-Name: "] = "Anmeldename: "; 303.498 ["Logout"] = "Abmelden"; 303.499 ["Logout successful"] = "Abmeldung erfolgreich"; 303.500 -["Manage filter"] = "Filter verwalten"; 303.501 -["Manage timeline filters"] = "Zeitachsen-Filter verwalten"; 303.502 +["Make your choice by placing the initiatives"] = "Treffe eine Wahl indem du die Initiativen verschiebst"; 303.503 +["Manage system settings"] = "Systemeinstellungen verwalten"; 303.504 ["Member"] = "Mitglied"; 303.505 -["Member '#{member}'"] = "Mitglied '#{member}'"; 303.506 ["Member has been removed from initiators"] = "Mitglied wurde von den Initiatoren entfernt"; 303.507 ["Member has been removed from your contacts"] = "Mitglied wurde aus Deinen Kontakten entfernt"; 303.508 ["Member has not approved latest draft"] = "Mitglied hat den letzten Entwurf noch nicht angenommen"; 303.509 -["Member has voting privileges for this unit"] = "Mitglied hat Stimmrecht in dieser Gliederung"; 303.510 ["Member inactive?"] = "Mitglied inaktiv?"; 303.511 ["Member is already saved in your contacts!"] = "Mitglied ist schon in Deinen Kontakten!"; 303.512 ["Member is not participating in any of the #{count} areas in this unit"] = "Mitglied nimmt an keinem der #{count} Themenbereiche dieser Gliederung teil"; 303.513 ["Member is not participating in the only area of the unit"] = "Mitglied nimmt am einzigen Themenbereich der Gliederung nicht teil"; 303.514 ["Member is now invited to be initiator"] = "Mitglied ist jetzt als Initiator eingeladen"; 303.515 -["Member is participating in this area"] = "Mitglied ist Teilnehmer im Themenbereich"; 303.516 ["Member list"] = "Mitgliederliste"; 303.517 ["Member menu"] = "Mitglieds-Menü"; 303.518 ["Member name"] = "Mitglied Name"; 303.519 -["Member name history for '#{name}'"] = "Namenshistorie für '#{name}'"; 303.520 -["Member of area"] = "Mitglied des Themenbereichs"; 303.521 -["Member page"] = "Mitgliederseite"; 303.522 ["Member successfully registered"] = "Mitglied erfolgreich registriert"; 303.523 ["Member successfully updated"] = "Mitglied erfolgreich aktualisert"; 303.524 -["Member: '#{identification}' (#{name})"] = "Mitglied: '#{identification}' (#{name})"; 303.525 ["Members"] = "Mitglieder"; 303.526 -["Membership not existent"] = "Mitgliedschaft existiert nicht"; 303.527 -["Membership removed"] = "Mitgliedschaft entfernt"; 303.528 -["Membership updated"] = "Mitgliedschaft aktualisiert"; 303.529 ["Memberships"] = "Mitgliedschaften"; 303.530 ["Missing help text: #{id}.#{lang}.txt"] = "Fehlender Hilfetext: #{id}.#{lang}.txt"; 303.531 ["Mobile phone"] = "Mobiltelefon"; 303.532 -["Monday"] = "Montag"; 303.533 ["Move down"] = "Runter schieben"; 303.534 ["Move up"] = "Hoch schieben"; 303.535 -["My areas"] = "Meine Themengebiete"; 303.536 -["My areas and issues"] = "Meine Themengebiete und Themen"; 303.537 +["My areas"] = "Meine Themenbereiche"; 303.538 ["My opinion"] = "Meine Meinung"; 303.539 -["My units"] = "Meine Gliederungen"; 303.540 ["Name"] = "Name"; 303.541 ["New"] = "Neu"; 303.542 -["New address"] = "Neue E-Mail-Adresse"; 303.543 -["New draft"] = "Neuer Entwurf"; 303.544 -["New draft has been added to initiative"] = "Neuer Entwurf wurde der Initiative hinzugefügt"; 303.545 +["New area"] = "Neues Themenbereich"; 303.546 +["New draft for initiative '#{initiative_name}'"] = "Neuer Entwurfstext von Initiative '#{initiative_name}'"; 303.547 ["New drafts for #{count} initiative(s) you are supporting"] = "Für #{count} von dir unterstützte Iniativen gibt es neue Entwürfe"; 303.548 ["New initiative"] = "Neue Initiative"; 303.549 ["New initiative draft"] = "Neuer Entwurfstext der Initiative"; 303.550 ["New issue"] = "Neues Thema"; 303.551 -["New password"] = "Neues Kennwort"; 303.552 +["New member"] = "Neues Mitglied"; 303.553 +["New organizational unit"] = "Neue Gliederung"; 303.554 ["New passwords does not match."] = "Du hast nicht zweimal das gleiche Kennwort eingegeben"; 303.555 ["New passwords is too short."] = "Das neue Kennwort ist zu kurz"; 303.556 +["New policy"] = "Neues Regelwerk"; 303.557 ["New suggestion"] = "Neue Anregung"; 303.558 ["Newest"] = "Neueste"; 303.559 ["No"] = "Nein"; 303.560 +["No (not yet)"] = "Nein (noch nicht)"; 303.561 ["No admission needed"] = "Keine Zulassung nötig"; 303.562 ["No changes to your images were made"] = "An Deinen Bildern wurde nichts geändert"; 303.563 ["No default"] = "Kein Standard"; 303.564 ["No delegation"] = "Keine Delegation"; 303.565 -["No events selected to list"] = "Keine Ereignisse ausgewählt"; 303.566 +["No matching issues found"] = "Keine passenden Themen gefunden"; 303.567 +["No matching members found"] = "Keine passenden Mitglieder gefunden"; 303.568 ["No more events available"] = "Keine weiteren Ereignisse verfügbar"; 303.569 ["No multistage majority"] = "Keine mehrstufigen Mehrheiten"; 303.570 -["No notifications at all"] = "Gar keine Benachrichtigungen"; 303.571 -["No potential supporters"] = "Keine potentiellen Unterstützer"; 303.572 -["No potential supporters (before begin of voting)"] = "Keine potentiellen Unterstützer (zum Abstimmungsbeginn)"; 303.573 +["No published contacts"] = "Keiner Kontakte veröffentlicht"; 303.574 +["No results for this selection"] = "Keine Ergebnisse für diese Auswahl"; 303.575 ["No reverse beat path"] = "Kein rückwärtsgerichteter Schlagpfad"; 303.576 ["No suggestions"] = "Keine Anregungen"; 303.577 ["No suggestions yet"] = "Noch keine Anregungen"; 303.578 -["No supporters"] = "Keine Unterstützer"; 303.579 -["No supporters (before begin of voting)"] = "Keine Unterstützer (zum Abstimmungsbeginn)"; 303.580 ["Not a member"] = "Kein Mitglied"; 303.581 -["Not accepted yet"] = "Bisher nicht angenommen"; 303.582 -["Not approved"] = "Nicht angenommen"; 303.583 -["Not approved (rank #{rank})"] = "Nicht angenommen (Rang #{rank})"; 303.584 -["Not voted"] = "Nicht abgestimmt"; 303.585 ["Not voted issues"] = "Nicht abgestimmt"; 303.586 ["Notification address unconfirmed"] = "E-Mail-Adresse für Benachrichtigungen unbestätigt"; 303.587 ["Notification email"] = "E-Mail für Benachrichtigungs"; 303.588 ["Notification level not set yet"] = "Benachrichtigungseinstellungen noch nicht vorgenommen"; 303.589 -["Notification settings"] = "Benachrichtigungseinstellungen"; 303.590 +["Notifications"] = "Benachrichtigungen"; 303.591 +["Notifications are only send to you about events in the subject areas you subscribed, the issues you are interested in and the initiatives you are supporting."] = "Benachrichtigungen werden nur für Ereignisse versendet, die deine Themenbereiche, Themen, und unterstützten Intiativen betreffen."; 303.592 ["Number of incoming delegations, follow link to see more details"] = "Anzahl eingehender Delegationen, Link folgen für mehr Details"; 303.593 ["OK"] = "OK"; 303.594 -["Old password"] = "Altes Kennwort"; 303.595 ["Old password is wrong"] = "Das alte Kennwort ist falsch"; 303.596 ["Oldest"] = "Älteste"; 303.597 ["On that page please enter the confirmation code:\n\n"] = "Auf dieser Seite gib bitten den folgenden Code ein:\n\n"; 303.598 ["On that page please enter the invite key:\n\n"] = "Auf dieser Seite gib den folgenden Code ein:\n\n"; 303.599 ["On that page please enter the reset code:\n\n"] = "Auf dieser Seite gib bitte den folgenden Rücksetzcode ein:\n\n"; 303.600 +["On this issue can be voted now."] = "Über dieses Thema kann jetzt abgestimmt werden."; 303.601 ["One issue"] = "Ein Thema"; 303.602 ["One issue you are interested in"] = "Ein Thema, das Dich interessiert"; 303.603 -["One more area in this unit"] = "Ein weiteres Themengebiet in dieser Gliederung"; 303.604 +["One more area in this unit"] = "Ein weiterer Themenbereich in dieser Gliederung"; 303.605 ["One of them have an area delegation set"] = "Bei einem davon ist eine Delegation für den Themenbereich gesetzt"; 303.606 -["One step back"] = "Ein Schritt zurück"; 303.607 ["Only for issues reaching the discussion phase"] = "Nur für Themen, die die Diskussion erreichen."; 303.608 -["Only for issues reaching the frozen phase"] = "Nur für Themen, die die Phase Eingefroren erreichen."; 303.609 +["Only for issues reaching the verification phase"] = "Nur für Themen, die die Überprüfung erreichen"; 303.610 ["Only for issues reaching the voting phase"] = "Nur für Themen, die die Abstimmung erreichen."; 303.611 -["Open"] = "Offen"; 303.612 ["Open initiatives you are supporting which has been updated their draft:"] = "Offene, von dir unterstützte Initiativen, deren Antragstext aktualisiert wurde:"; 303.613 ["Open issues"] = "Offene Themen"; 303.614 +["Open the appropriate subject area where your issue fits in and follow the instruction on that page."] = "Den passenden Themenbereich öffnen und dort den Anweisungen folgen."; 303.615 ["Opinions"] = "Meinungen"; 303.616 ["Options"] = "Optionen"; 303.617 ["Organizational unit"] = "Organisationseinheit"; 303.618 +["Organizational units"] = "Organisationseinheiten"; 303.619 +["Organizational units and subject areas"] = "Organisationseinheiten und Themenbereiche"; 303.620 ["Other failures"] = "Weitere Mängel"; 303.621 ["Outgoing delegations"] = "Ausgehende Delegationen"; 303.622 +["Page not found"] = "Seite nicht gefunden"; 303.623 +["Paragraphs"] = "Absätze"; 303.624 ["Parent unit"] = "Übergeordnete Gliederung"; 303.625 -["Participants"] = "Teilnehmer"; 303.626 -["Participate in this area"] = "An diesem Themengebiet teilnehmen"; 303.627 ["Password"] = "Kennwort"; 303.628 ["Password (repeat)"] = "Kennwort (wiederholen)"; 303.629 ["Password has been reset successfully"] = "Kennwort wurde erfolgreich zurückgesetzt"; 303.630 ["Password reset request"] = "Kennwort-Rücksetzung anfordern"; 303.631 ["Passwords don't match!"] = "Kennwörter stimmen nicht überein!"; 303.632 ["Passwords must consist of at least 8 characters!"] = "Das Kennwort muss zumindest 8 Zeichen lang sein!"; 303.633 -["Phases"] = "Phasen"; 303.634 +["Phase durations"] = "Phasendauer"; 303.635 ["Phone"] = "Telefon"; 303.636 ["Photo"] = "Foto"; 303.637 ["Please choose a login name. This name will not be shown to others and is used only by you to login into the system. The login name is case sensitive."] = "Bitte wähle einen Anmeldenamen. Dieser wird anderen nicht gezeigt und nur von Dir zum Anmelden verwendet. Groß- und Kleinschreibung wird berücksichtigt."; 303.638 @@ -455,13 +478,15 @@ 303.639 ["Please choose a name, i.e. your real name or your nick name. This name will be shown to others to identify you."] = "Wähle einen Namen, z. B. Deinen Real- oder Nicknamen. Dieser wird anderen angezeigt um Dich zu identifizieren."; 303.640 ["Please choose a password and enter it twice. The password is case sensitive."] = "Bitte wähle ein Kennwort und gib es zweimal ein. Groß- und Kleinschreibung wird berücksichtigt."; 303.641 ["Please choose a policy"] = "Bitte wähle ein Regelwerk"; 303.642 +["Please choose a policy for the new issue:"] = "Bitte ein Regelwerk für das neue Thema auswählen:"; 303.643 +["Please choose an area name"] = "Bitte einen Namen für den Themenbereich wählen"; 303.644 ["Please choose two different versions of the draft to compare"] = "Bitte wähle zwei verschiedene Versionen des Entwurfs, um sie zu vergleichen."; 303.645 -["Please choose two versions of the draft to compare"] = "Bitte wähle zwei Versionen des Entwurfs, um sie zu vergleichen."; 303.646 ["Please confirm your email address"] = "Bitte bestätige Deine E-Mail-Adresse"; 303.647 ["Please confirm your email address by clicking the following link:\n\n"] = "Bitte bestätige Deine E-Mail-Adresse durch Klick auf folgenden Link:\n\n"; 303.648 ["Please decide for each delegation to confirm or to revoke it!"] = "Für jede Delegation muss eine Entscheidung getroffen werden!"; 303.649 +["Please enter a meaningful title for your initiative!"] = "Bitte einen aussagekräftigen Titel für die Initiative eingeben!"; 303.650 ["Please enter the email reset code you have received:"] = "Bitte gib den Rücksetzcode ein, den Du erhalten hast:"; 303.651 -["Please enter the invite code you've received."] = "Bitte gib den Einladungscode ein, den Du erhalten hast."; 303.652 +["Please enter the invite code you've received"] = "Bitte den erhaltenen Einladungscode eingeben"; 303.653 ["Please enter your email address. This address will be used for automatic notifications (if you request them) and in case you've lost your password. This address will not be published. After registration you will receive an email with a confirmation link."] = "Bitte gib Deine E-Mail-Adresse ein. Diese Adresse wird für automatische Benachrichtigungen (wenn Du diese anforderst) sowie zum Zurücksetzen des Kennworts verwendet. Diese Adresse wird nicht veröffentlicht. Nach Abschluss der Registrierung wirst Du eine E-Mail mit einem Link zum Bestätigen der Adresse erhalten."; 303.654 ["Please enter your email address. You will receive an email with your login name."] = "Bitte die E-Mail-Adresse eingeben. An diese wird eine Nachricht mit dem zugehörigen Anmeldenamen versendet."; 303.655 ["Please enter your login name. You will receive an email with a link to reset your password."] = "Bitte gib Deinen Anmeldenamen ein. Du wirst eine E-Mail mit einem Link zum Zurücksetzen des Kennworts erhalten."; 303.656 @@ -474,102 +499,110 @@ 303.657 ["Polling mode"] = "Befragungsmodus"; 303.658 ["Population"] = "Grundgesamtheit"; 303.659 ["Posts"] = "Ämter"; 303.660 -["Potential supported"] = "Potentiell unterstützt"; 303.661 -["Potential supporters"] = "Potentielle Unterstützer"; 303.662 -["Potential supporters (before begin of voting)"] = "Potentielle Unterstützer (zum Abstimmungsbeginn)"; 303.663 -["Potentially supported"] = "Potentiell unterstützt"; 303.664 +["Preference comparison"] = "Präferenzvergleich"; 303.665 +["Preference voting"] = "Präferenzabstimmung"; 303.666 ["Preview"] = "Vorschau"; 303.667 -["Preview voting comment"] = "Vorschau Abstimmmungskommentar"; 303.668 -["Proceed with registration"] = "Registrierung fortsetzen"; 303.669 +["Preview of delegation"] = "Vorschau der Delegation"; 303.670 +["Preview of voting ballot"] = "Vorschau des Stimmzettels"; 303.671 +["Private contacts"] = "Kontakte (nicht veröffentlicht)"; 303.672 ["Profession"] = "Beruf"; 303.673 -["Profile"] = "Profil"; 303.674 -["Public administrative notice:"] = "Administrativer Hinweistext (öffentlich)"; 303.675 ["Publish"] = "Veröffentlichen"; 303.676 +["Publish now"] = "Jetzt veröffentlichen"; 303.677 ["Published"] = "veröffentlicht"; 303.678 -["Quorum"] = "Quorum"; 303.679 +["Published contacts"] = "Veröffentlichte Kontakte"; 303.680 +["Put **double asterisks** around a phrase to make it bold"] = "Für fetten Text, diesen in **doppelten Sternchen** einschließen"; 303.681 +["Put *asterisks* or around a phrase to make it italic"] = "Für kursiven Text, diesen in *einfache Sternchen* einschließen"; 303.682 +["Put a hypen (-) or asterisk (*) followed by a space in front of each item"] = "Einen Strich (-) oder Sternchen (*) gefolgt von einem Leerschritt vor jeden Listenpunkt setzen"; 303.683 +["Quorums"] = "Quoren"; 303.684 +["Reached #{sign}#{num}/#{den}"] = "#{sign}#{num}/#{den} erreicht"; 303.685 +["Read and accept the terms and choose a password"] = "Nutzungsbedingungen akzeptieren und ein Kennwort wählen"; 303.686 +["Read more"] = "Mehr lesen"; 303.687 ["Real name"] = "Realname"; 303.688 -["Refresh support to current draft"] = "Unterstützung auf aktuellen Entwurf aktualisieren"; 303.689 -["Refuse invitation"] = "Einladung ablehnen"; 303.690 +["Recover login name"] = "Login-Namen wiederherstellen"; 303.691 ["Register new member"] = "Neues Mitglied registrieren"; 303.692 +["Registered members (#{count})"] = "Registrierte Teilnehmer (#{count})"; 303.693 ["Registration"] = "Registrierung"; 303.694 ["Registration (step 1 of 3: Invite code)"] = "Registrierung (Schritt 1 von 3: Einladungscode)"; 303.695 ["Registration (step 2 of 3: Personal information)"] = "Registrierung (Schritt 2 von 3: Persönliche Daten)"; 303.696 ["Registration (step 3 of 3: Terms of use and password)"] = "Registrierung (Schritt 3 von 3: Nutzungsbedingungen und Kennwort)"; 303.697 ["Rejected"] = "Abgelehnt"; 303.698 +["Rejected (rank #{rank})"] = "Abgelehnt (#{rank}. Platz)"; 303.699 ["Remove"] = "Entfernen"; 303.700 -["Remove from contacts"] = "Aus den Kontakten entfernen"; 303.701 +["Remove an initiator from initiative"] = "Einen Initiator entfernen"; 303.702 ["Remove initiator"] = "Initiator entfernen"; 303.703 -["Remove initiator from initiative"] = "Initiator von der Initiative entfernen"; 303.704 ["Rendered"] = "Formatiert"; 303.705 -["Repeat new password"] = "Neues Kennwort wiederholen"; 303.706 ["Request email with login name"] = "E-Mail mit Anmeldename anfordern"; 303.707 -["Request password reset link"] = "Link zum Rücksetzen des Kennworts anfordern"; 303.708 +["Request password reset link"] = "Rücksetzlink per E-Mail anfordern"; 303.709 ["Resend activation email to '#{email}'"] = "E-Mail mit Aktivierungslink erneut an '#{email}' senden"; 303.710 ["Reset code"] = "Rücksetzcode"; 303.711 ["Reset code is invalid!"] = "Rücksetzcode ist ungültig"; 303.712 ["Reset password"] = "Kennwort zurücksetzen"; 303.713 ["Revoke initiative"] = "Initiative zurückziehen"; 303.714 +["Revoke now"] = "Jetzt zurückziehen"; 303.715 +["Revoked (during admission)"] = "Zurückgezogen (während der Zulassung)"; 303.716 +["Revoked (during discussion)"] = "Zurückgezogen (während der Diskussion)"; 303.717 +["Revoked (during verification)"] = "Zurückgezogen (während der Überprüfung)"; 303.718 ["Revoked at"] = "Zurückgezogen am/um"; 303.719 -["Saturday"] = "Samstag"; 303.720 +["Rules of procedure"] = "Regelwerke"; 303.721 ["Save"] = "Speichern"; 303.722 -["Save current filter"] = "Aktuellen Filter speichern"; 303.723 -["Save timeline filters"] = "Zeitachsen-Filter speichern"; 303.724 -["Saved as contact"] = "Als Kontakt gespeichert"; 303.725 +["Save new password"] = "Neues Kennwort speichern"; 303.726 +["Save voting comment"] = "Abstimmungskommentar speichern"; 303.727 ["Saved contacts"] = "Gespeicherte Kontakte"; 303.728 ["Schulze rank"] = "Schulze-Rang"; 303.729 ["Screen name"] = "Screen-Name"; 303.730 ["Search"] = "Suchen"; 303.731 -["Search context"] = "Suchkontext"; 303.732 -["Search for issues"] = "Nach Themen suchen"; 303.733 -["Search for members"] = "Nach Mitgliedern suchen"; 303.734 ["Search initiatives"] = "Suche Initiativen"; 303.735 ["Search issues"] = "Suche Themen"; 303.736 ["Search members"] = "Suche Mitglieder"; 303.737 ["Search results for: '#{search}'"] = "Suchergebnisse für: '#{search}'"; 303.738 ["Search term (only complete words)"] = "Suchbegriff(e) (nur ganze Wörter)"; 303.739 -["Select language"] = "Sprache wählen"; 303.740 +["Select a notification level"] = "Ein Meldestufe für Benachrichtigungen auswählen"; 303.741 ["Select language \"#{langcode}\""] = "Sprache \"#{langcode}\" wählen"; 303.742 ["Send invite?"] = "Einladung schicken?"; 303.743 +["Separate each paragraph with at least one blank line"] = "Jeden Absatz mit zumindest einer Leerzeile vom nächsten trennen"; 303.744 ["Set URL"] = "URL setzen"; 303.745 -["Set delegation for Area '#{name}'"] = "Delegation für Themenbereich '#{name}' festlegen"; 303.746 -["Set delegation for Issue ##{number} in Area '#{area_name}'"] = "Delegation für Thema ##{number} im Themenbereich '#{area_name}' festlegen"; 303.747 -["Set global delegation"] = "Globale Delegation festlegen"; 303.748 -["Set new password"] = "Neues Kennwort setzen"; 303.749 +["Set area delegation"] = "Themenbereich delegieren"; 303.750 +["Set issue delegation"] = "Thema delegieren"; 303.751 ["Set unit delegation"] = "Delegation für Gliederung setzen"; 303.752 ["Settings"] = "Einstellungen"; 303.753 +["Should the initiator implement this suggestion?"] = "Soll der Initiator diese Anregung umsetzen?"; 303.754 ["Show"] = "Zeige"; 303.755 +["Show all members"] = "Alle Mitglieder anzeigen"; 303.756 ["Show areas in use"] = "Zeige verwendete Themenbereiche"; 303.757 ["Show areas not in use"] = "Zeige nicht verwendete Themenbereiche"; 303.758 -["Show diff"] = "Änderungen anzeigen"; 303.759 -["Show filter details"] = "Zeige Filter-Details"; 303.760 +["Show full history"] = "Komlette Historie anzeigen"; 303.761 +["Show full member list"] = "Komplette Mitgliederliste anzeigen"; 303.762 ["Show help text"] = "Zeige Hilfe-Text"; 303.763 ["Show inactive units"] = "Zeige deaktivierte Gliederungen"; 303.764 +["Show less"] = "Weniger anzeigen"; 303.765 ["Show member"] = "Mitglied anzeigen"; 303.766 -["Show member history"] = "Historie des Mitglieds anzeigen"; 303.767 +["Show more and rate this"] = "Mehr zeigen und bewerten"; 303.768 +["Show my voting ballot"] = "Meinen Stimmzettel anzeigen"; 303.769 ["Show older events"] = "Zeige ältere Ereignisse"; 303.770 -["Show only events which match... (or associtated)"] = "Zeige nur Ereignisse welche folgendes erfüllen... (oder-verknüpft)"; 303.771 ["Show policies in use"] = "Zeige Regelwerke in Verwendung"; 303.772 ["Show policies not in use"] = "Zeige deaktivierte Regelwerke"; 303.773 ["Show profile"] = "Profil anzeigen"; 303.774 +["Show voting ballot"] = "Stimmzettel anzeigen"; 303.775 ["So I'm"] = "Also bin ich"; 303.776 -["Software"] = "Software"; 303.777 ["Sorry, but there is not confirmed email address for your account. Please contact the administrator or support."] = "Sorry, aber für diesen Account ist keine bestätigte E-Mail-Adresse hinterlegt. Bitte wende Dich an den Administrator oder den Support."; 303.778 ["Sorry, but you are currently not invited"] = "Sorry, aber Du bist zur Zeit nicht eingeladen"; 303.779 ["Sorry, you have reached your personal flood limit. Please be slower..."] = "Sorry, Du hast Dein persönliches Flood-Limit erreicht. Bitte sei langsamer..."; 303.780 ["Sorry, your contingent for creating initiatives has been used up. Please try again later."] = "Sorry, Dein Antragskontingent ist zur Zeit ausgeschöpft. Bitte versuche es später erneut!"; 303.781 ["Source"] = "Quelltext"; 303.782 ["Standard policies"] = "Standardverfahren"; 303.783 -["Start search"] = "Suche starten"; 303.784 ["Statement"] = "Statement"; 303.785 ["Status"] = "Status"; 303.786 ["Status quo: #{rank}"] = "Status quo: #{rank}"; 303.787 -["Stop ignoring member"] = "nicht mehr ignorieren"; 303.788 ["Strict direct majority"] = "Strenge direkte Mehrheit"; 303.789 ["Strict indirect majority"] = "Strenge indirekte Mehrheit"; 303.790 -["Stylesheet URL"] = "Stylesheet URL"; 303.791 +["Structured discussion"] = "Strukturierte Diskussion"; 303.792 ["Stylesheet URL has been updated"] = "Stylesheet URL wurde aktualisiert"; 303.793 +["Subject area subscribed"] = "für Themenbereich angemeldet"; 303.794 +["Subject areas"] = "Themenbereiche"; 303.795 +["Subscribed members (#{count})"] = "Angemeldete Teilnehmer (#{count})"; 303.796 +["Subscription already removed"] = "bereits abgemeldet"; 303.797 +["Subscription removed"] = "vom Themenbereich erfolgreich abgemeldet"; 303.798 ["Suggest no initiative"] = "Keine Initiative empfehlen"; 303.799 -["Suggested initiative"] = "Empfohlene Initiative"; 303.800 ["Suggestion"] = "Anregung"; 303.801 ["Suggestion ##{id}"] = "Anregung ##{id}"; 303.802 ["Suggestion currently implemented"] = "Anregung zur Zeit umgesetzt"; 303.803 @@ -577,86 +610,74 @@ 303.804 ["Suggestion does not exist anymore"] = "Anregung existiert nicht mehr"; 303.805 ["Suggestion for initiative: '#{name}'"] = "Anregung für Initiative '#{name}'"; 303.806 ["Suggestions"] = "Anregungen"; 303.807 -["Sunday"] = "Sonntag"; 303.808 +["Suggestions for improvement (#{count})"] = "Verbesserungsvorschläge (#{count})"; 303.809 ["Support this initiative"] = "Diese Initiative unterstützen"; 303.810 -["Supported"] = "Unterstützt"; 303.811 -["Supporters"] = "Unterstützer"; 303.812 -["Supporters (before begin of voting)"] = "Unterstützer (zum Abstimmungesbeginn)"; 303.813 ["Syntax help"] = "Syntax-Hilfe"; 303.814 +["System administration"] = "Systemadministration"; 303.815 +["System settings"] = "Systemeinstellungen"; 303.816 +["Take a look through the existing issues. Maybe someone else started a debate on your topic (and you can join it) or the topic has been decided already in the past."] = "Schau dir die bestehenden Themen an. Vielleicht hat schon jemand eine Debatte über dein Thema gestartet (und du kannst daran teilnehmen) oder über das Thema wurde bereits in der Vergangenheit entschieden."; 303.817 +["Tell others about this initiative:"] = "Anderen von dieser Initiative berichten:"; 303.818 ["Terms of use"] = "Nutzungsbedingungen"; 303.819 ["The code you've entered is invalid"] = "Der Code, den Du eingeben hast, ist nicht gültig!"; 303.820 ["The draft of this initiative has been updated!"] = "Der Entwurfstext der Initiative wurde aktualisiert!"; 303.821 ["The drafts do not differ"] = "Die Entwürfe unterscheiden sich nicht"; 303.822 +["The initiative draft has been updated again in the meanwhile, support not updated!"] = "Der Entwurfstext der Initiative wurde zwischenzeitlich erneut geändert, die Unterstützung wurde daher nicht aktualisiert!"; 303.823 +["The initiative text has been updated"] = "Der Entwurfstext der Initiative wurde geändert"; 303.824 ["The initiators suggest to support the following initiative:"] = "Die Initiatoren empfehlen folgende Initiative zu unterstützen:"; 303.825 +["The title is the figurehead of your iniative. It should be short but meaningful! As others identifies your initiative by this title, you cannot change it later!"] = "Der Titel ist das Aushängeschild einer Initiative. Er sollte bedeutungsvoll sein! Da die Initiative durch den Titel identifiziert wird, kann er später nicht mehr geändert werden!"; 303.826 +["This delegation is suspended, because you voted yourself."] = "Die Delegation wurde durch eigenes Abstimmen ausgesetzt."; 303.827 ["This email address is too short!"] = "Diese E-Mail-Adresse ist zu kurz!"; 303.828 ["This initiative"] = "Diese Initiative"; 303.829 -["This initiative has been revoked at #{revoked}"] = "Diese Initiative wurde am/um #{revoked} zurückgezogen"; 303.830 -["This initiative has not been admitted! It failed the quorum of #{quorum}."] = "Diese Initiative wurde nicht zugelassen. Sie hat das Quorum von #{quorum} nicht erreicht."; 303.831 +["This initiative has been revoked at #{revoked} by:"] = "Diese Initiative wurde am/um #{revoked} zurückgezogen, von:"; 303.832 +["This initiative has not been admitted! It failed the 2nd quorum of #{quorum}."] = "Diese Initiative wurde nicht zugelassen! Sie ist am 2. Quorum (#{quorum}) gescheitert."; 303.833 ["This initiative is already revoked"] = "Diese Initiative ist schon zurückgezogen"; 303.834 ["This initiative is revoked"] = "Diese Initiative wurde zurückgezogen"; 303.835 ["This invite key is connected with the following information:"] = "Dieser Einladungscode ist mit den folgenden Daten verknüpft:"; 303.836 -["This issue has been canceled by administrative intervention."] = "Dieses Thema wurde durch administrativen Eingriff abgebrochen."; 303.837 -["This issue has been canceled."] = "Dieses Thema wurde abgebrochen"; 303.838 -["This issue has been canceled. It failed the quorum of #{quorum}."] = "Dieses Thema wurde abgebrochen. Es hat das Quorum von #{quorum} nicht erfüllt."; 303.839 +["This is the only initiative in this issue, because nobody started a competing initiative."] = "Dies ist die einzige Initiative in diesem Thema, da niemand eine konkurrierende Initiative gestartet hat."; 303.840 ["This issue is already closed."] = "Das Thema ist schon geschlossen."; 303.841 ["This issue is already frozen."] = "Das Thema ist schon eingefroren"; 303.842 +["This issue is closed"] = "Das Thema ist geschlossen"; 303.843 ["This login is already taken, please choose another one!"] = "Dieser Anmeldename ist bereits vergeben, bitte wähle einen anderen!"; 303.844 ["This login is too short!"] = "Dieser Anmeldename ist zu kurz!"; 303.845 ["This member account has been created at #{created}"] = "Dieser Mitgliedszugang wurde am/um #{created} angelegt."; 303.846 ["This member has rejected to become initiator of this initiative"] = "Dieses Mitglied hat die Einladung, Initiator zu werden, abgelehnt"; 303.847 ["This member is already initiator of this initiative"] = "Dieses Mitglied ist bereits Initiator dieser Initiative"; 303.848 ["This member is already invited to become initiator of this initiative"] = "Dieses Mitglied ist bereits eingeladen Initiator dieser Initiative zu werden"; 303.849 +["This member is currently participating in this issue."] = "Dieses Mitglied nimmt zur Zeit an diesem Thema teil."; 303.850 ["This member is inactive"] = "Mitglied ist inaktiv"; 303.851 -["This member is initiator of this initiative"] = "Dieses Mitglied ist Initiator dieser Initiative"; 303.852 ["This member is locked"] = "Mitglied ist gesperrt"; 303.853 -["This member is participating, the rest of delegation chain is suspended while discussing"] = "Dieses Mitglied partizipiert, Rest der Delegationskette während der Diskussion ausgesetzt."; 303.854 -["This member is potential supporter of this initiative"] = "Dieses Mitglied ist potentieller Unterstützer dieser Initiative"; 303.855 -["This member is potential supporter of this initiative via delegation"] = "Dieses Mitglied ist durch Delegation potentieller Unterstützer dieser Initiative"; 303.856 -["This member is supporter of this initiative"] = "Dieses Mitglied ist Unterstützer dieser Initiative"; 303.857 -["This member is supporter of this initiative via delegation"] = "Dieses Mitglied ist durch Delegation Unterstützer dieser Initiative"; 303.858 +["This member is participating, the remaining delegation chain is suspended during discussing."] = "Diese Mitglied nimmt am Thema teil, daher sind die folgenden Delegationen während der Diskussion ausgesetzt."; 303.859 ["This name is already taken, please choose another one!"] = "Dieser Name ist bereits vergeben, bitte wähle einen anderen!"; 303.860 -["This name is really too short!"] = "Dieser Name ist wirklich zu kurz!"; 303.861 ["This name is too short!"] = "Dieser Name ist zu kurz!"; 303.862 ["This screen name is too short!"] = "Dieser Screen-Name ist zu kurz!"; 303.863 ["This service is provided by:"] = "Diensteanbieter:"; 303.864 ["This service is provided using the following software components:"] = "Dieser Dienst ist mit folgender Software realisiert worden:"; 303.865 -["This site is using"] = "Diese Seite benutzt"; 303.866 ["This suggestion has been meanwhile deleted"] = "Diese Anregung wurde zwischenzeitlich gelöscht"; 303.867 ["This title is really too short!"] = "Dieser Titel ist wirklich zu kurz!"; 303.868 -["Thursday"] = "Donnerstag"; 303.869 -["Timeline"] = "Zeitachse"; 303.870 +["This title is too long!"] = "Der Titel ist zu lang!"; 303.871 ["Title"] = "Titel"; 303.872 -["Title (80 chars max)"] = "Titel (max. 80 Zeichen)"; 303.873 -["Title of initiative"] = "Titel der Initiative"; 303.874 -["Today at #{time}"] = "Heute um #{time}"; 303.875 -["Traditional wiki syntax"] = "Traditionelle Wiki-Syntax"; 303.876 -["Trustee"] = "Bevollmächtigter"; 303.877 +["To create a competing initiative see below."] = "Um eine konkurrierende Initiative zu starten siehe unten."; 303.878 ["Trustee has no voting right in this unit"] = "Bevollmächtigter hat kein Stimmrecht in dieser Gliederung"; 303.879 -["Tuesday"] = "Dienstag"; 303.880 -["Unconfirmed address"] = "Unbestätigte E-Mail"; 303.881 +["Underline main headlines with ==="] = "Haupt-Überschriften mit === unterstreichen"; 303.882 +["Underline sub headlines with ---"] = "Unter-Überschriften mit --- unterstreichen"; 303.883 ["Unit"] = "Gliederung"; 303.884 -["Unit '#{name}'"] = "Gliederung '#{name}'"; 303.885 ["Unit delegation"] = "Gliederungsdelegation"; 303.886 ["Unit list"] = "Liste der Gliederungen"; 303.887 -["Unit: '#{name}'"] = "Gliederung: '#{name}'"; 303.888 -["Units"] = "Gliederungen"; 303.889 -["Units and areas"] = "Gliederungen und Themengebiete"; 303.890 ["Unknown author"] = "Unbekannter Autor"; 303.891 -["Update voting comment"] = "Abstimmungskommentar ändern"; 303.892 ["Updated drafts"] = "Neue Entwürfe"; 303.893 ["Upload avatar/photo"] = "Avatar/Foto hochladen"; 303.894 -["Upload images"] = "Bilder hochladen"; 303.895 +["Use [Text](http://example.com/) for links"] = "[Text](http://example.com/) verwenden für Links"; 303.896 ["Use terms"] = "Nutzungsbedingungen"; 303.897 +["Verification"] = "Überprüfung"; 303.898 +["Verification #{time_info}"] = false; 303.899 ["Verification started"] = "Phase Eingefroren gestartet"; 303.900 -["Verification starts soon"] = "Phase Eingefroren startet in Kürze"; 303.901 ["Verification time"] = "Zeit für Eingefroren"; 303.902 -["Version"] = "Version"; 303.903 -["Vote now"] = "Jetzt abstimmen"; 303.904 -["Voted"] = "Abgestimmt"; 303.905 +["Vote delegation"] = "Stimmdelegation"; 303.906 ["Voted no"] = "Mit Nein gestimmt"; 303.907 ["Voted yes"] = "Mit Ja gestimmt"; 303.908 ["Voters"] = "Abstimmende"; 303.909 ["Voting"] = "Abstimmung"; 303.910 +["Voting #{time_info}"] = false; 303.911 ["Voting comment"] = "Abstimmungskommentar"; 303.912 ["Voting comment (last updated: #{timestamp})"] = "Abstimmmungskommentar (Letzte Änderung: #{timestamp})"; 303.913 ["Voting comment (optional)"] = "Abstimmmungskommentar (optional)"; 303.914 @@ -664,75 +685,87 @@ 303.915 ["Voting for this issue has already begun."] = "Die Abstimmung für dieses Thema hat schon begonnen."; 303.916 ["Voting has not started yet."] = "Die Abstimmung hat noch nicht begonnen."; 303.917 ["Voting started"] = "Abstimmung begonnen"; 303.918 -["Voting starts soon"] = "Abstimmung beginnt in Kürze"; 303.919 ["Voting time"] = "Zeit für die Abstimmung"; 303.920 ["We couldn't deliver a confirmation mail to this address. Please check entered email address."] = "Wir konnten keine Bestätigungs-E-Mail versenden. Bitte überprüfe die E-Mail-Adresse."; 303.921 ["We have sent an email with activation link already in the last hour. Please try again later."] = "Wir haben bereits innerhalb der letzten Stunde eine E-Mail mit Bestätigungslink gesendet. Bitte versuche es später erneut."; 303.922 ["Website"] = "Webseite"; 303.923 -["Wednesday"] = "Mittwoch"; 303.924 +["What can I do here?"] = "Was kann ich hier machen?"; 303.925 +["What this member is currently supporting"] = "Was dieses Mitglied zur Zeit unterstützt"; 303.926 ["Wiki engine"] = "Wiki engine"; 303.927 ["Wiki engine for statement"] = "Wiki engine für das Statement"; 303.928 ["Withdraw"] = "Zurückziehen"; 303.929 ["Withdraw membership"] = "Mitgliedschaft aufgeben"; 303.930 ["Yes"] = "Ja"; 303.931 -["Yesterday at #{time}"] = "Gestern um #{time}"; 303.932 +["Yes, it's implemented"] = "Ja, ist umgesetzt"; 303.933 ["You already voted this issue"] = "Du hast dieses Thema bereits abgestimmt"; 303.934 ["You are already initiator"] = "Du bist bereits Initiator"; 303.935 -["You are already not supporting this initiative"] = "Diese Initiative hat bereits keine Unterstützung von Dir"; 303.936 ["You are already supporting the latest draft"] = "Du unterstützt bereits den neuesten Entwurf"; 303.937 ["You are currently not invited to any initiative."] = "Du bist zur Zeit von keiner Initiative eingeladen."; 303.938 ["You are currently not supporting this initiative directly. By adding suggestions to this initiative you will automatically become a potential supporter."] = "Du bist zur Zeit kein direkter Unterstützer dieser Initiative. Wenn Du eine Anregung hinzufügst wirst Du automatisch potentieller Unterstützer!"; 303.939 ["You are initiator of this initiative"] = "Du bist Initiator dieser Initiative"; 303.940 -["You are interested"] = "Du bist interessiert"; 303.941 ["You are interested in this issue"] = "Du bist an diesem Thema interessiert"; 303.942 ["You are invited to #{count} initiative(s)"] = "Du bist zu #{count} Initiativen als Initiator eingeladen"; 303.943 ["You are invited to LiquidFeedback. To register please click the following link:\n\n"] = "Du bist zu LiquidFeedback eingeladen. Bitte klicke auf den folgenden Link, um dich zu registrieren:\n\n"; 303.944 -["You are invited to become initiator of this initiative."] = "Du bist eingeladen Initiator dieser Initiative zu werden."; 303.945 +["You are invited to become initiator of '#{initiative_name}'"] = "Einladung Initiator der Initiative '#{initiative_name}' zu werden"; 303.946 +["You are invited to become initiator of this initiative"] = "Du bist eingeladen Initiator dieser Initiative zu werden"; 303.947 ["You are member"] = "Du bist Mitglied"; 303.948 +["You are not eligible to participate"] = "Du bist nicht teilnahmeberechtigt"; 303.949 +["You are not entitled to vote in this unit"] = "Du bist in dieser Gliederung nicht stimmberechtigt"; 303.950 ["You are not participating in any of the #{count} areas in this unit"] = "Du nimmst an keinem der #{count} Themenbereiche dieser Gliederung teil"; 303.951 ["You are not participating in the only area of the unit"] = "Du nimmst am einzigen Themenbereich der Gliederung nicht teil"; 303.952 ["You are now initiator of this initiative"] = "Du bist jetzt Initiator dieser Initiative"; 303.953 -["You are participating in this area"] = "Du bist Teilnehmer im Themengebiet"; 303.954 ["You are potential supporter"] = "Du bist potentieller Unterstützer"; 303.955 -["You are potential supporter of this initiative"] = "Du bist potentieller Unterstützer der Initiative"; 303.956 -["You are potential supporter of this initiative via delegation"] = "Du bist durch Delegation potentieller Unterstützer der Initiative"; 303.957 +["You are subscribed for this subject area"] = "Du bist für diesen Themenbereich angemeldet"; 303.958 ["You are supporter"] = "Du bist Unterstützer"; 303.959 -["You are supporter of this initiative"] = "Du bist Unterstützer dieser Initiative"; 303.960 -["You are supporter of this initiative via delegation"] = "Du bist durch Delegation Unterstützer dieser Initiative"; 303.961 +["You are supporting this initiative"] = "Du unterstützt diese Initiative"; 303.962 +["You blocked this member (i.e. you will not be notified about this members actions)"] = "Du hast dieses Mitglied geblockt (d.h. du wirst nicht mehr über dessen Aktivitäten informiert)"; 303.963 ["You can change your email address only once per hour. Please try again later."] = "Du kannst die E-Mail-Adresse nur einmal in der Stunde ändern, bitte versuche es später erneut."; 303.964 +["You can change your text again anytime during admission and discussion phase"] = "Du kannst den Text während der Zulassungs- und Diskussionsphase jederzeit wieder ändern"; 303.965 +["You can choose only members which you have been saved as contact before."] = "Du kannst nur Mitglieder ausählen, die du zuvor als Kontakt gespeichert hast."; 303.966 ["You can't suggest the initiative you are revoking"] = "Du kannst nicht die Initiative empfehlen, die Du löschen möchtest"; 303.967 +["You cannot change your text again later, because this issue is already in verfication phase!"] = "Du kannst den Text später nicht mehr ändern, da das Thema bereits in der Überprüfungsphase ist!"; 303.968 +["You delegated this issue"] = "Du hast dieses Thema delegiert"; 303.969 +["You delegated this organizational unit"] = "Du hast diese Gliederung delegiert"; 303.970 +["You delegated this subject area"] = "Du hast diesen Themenbereich delegiert"; 303.971 +["You delegated this unit"] = "Du hast diese Gliederung delegiert"; 303.972 ["You didn't confirm your email address '#{email}' within 7 days."] = "Du hast die E-Mail-Adresse '#{email}' nicht innerhalb von 7 Tagen bestätigt."; 303.973 ["You didn't confirm your email address '#{email}'. You have received an email with an activation link."] = "Du hast die E-Mail-Adresse '#{email}' nicht bestätigt. Du hast hierzu eine E-Mail mit einem Aktivierungslink erhalten."; 303.974 ["You didn't save any member as contact yet."] = "Du hast noch kein Mitglied als Kontakt gespeichert!"; 303.975 ["You didn't set the level of notifications you like to receive"] = "Du hast noch nicht ausgewählt, ob und welche Benachrichtigungen du erhalten möchtest."; 303.976 -["You have ignored this member"] = "Du ignorierst dieses Mitglied"; 303.977 +["You do not like to vote this issue (yourself)"] = "Du möchtest für dieses Thema nicht (selber) abstimmen"; 303.978 +["You have been voted"] = "Du hast abgestimmt"; 303.979 ["You have not voted #{count} issue(s) you were interested in"] = "Du hast für #{count} Themen, die dich interessieren, noch nicht abgestimmt"; 303.980 ["You have to mark 'Are you sure' to revoke!"] = "Zum Zurückziehen musst Du 'Sicher?' auswählen"; 303.981 -["You have voting privileges for this unit"] = "Du hast Stimmrecht in dieser Gliederung"; 303.982 -["You need to be logged in, to use all features of this system."] = "Du musst eingeloggt sein, um alle Funktionen dieses Systems nutzen zu können."; 303.983 -["You were interested"] = "Du warst interessiert"; 303.984 +["You have voted"] = "Du hast abgestimmt"; 303.985 +["You have voted via delegation"] = "Du hast per Delegation abgestimmt"; 303.986 +["You may choose one of the ongoing initiatives you are currently supporting"] = "Du kannst eine der noch laufenden Initiativen auswählen, die du direkt unterstützt."; 303.987 +["You refused to become initiator of this initiative"] = "Du hast abgelehnt Initiator dieser Initiative zu werden"; 303.988 +["You saved this member as contact (i.e. to use as delegatee)"] = "Du hast dieses Mitglied gespeichert (z.B. um es als Delegierten zu verwenden)"; 303.989 +["You saved this member as contact (i.e. to use as delegatee) and others can see it"] = "Du hast dieses Mitglied gespeichert (z.B. um es als Delegierten zu verwenden) und andere können das sehen"; 303.990 ["You were potential supporter"] = "Du bist potentieller Unterstützer"; 303.991 ["You were supporter"] = "Du bist Unterstützer"; 303.992 ["You've successfully registered and you can login now with your login and password!"] = "Du hast Dich erfolgreich registriert und kannst Dich jetzt mit Deinen Anmeldenamen und Kennwort anmelden!"; 303.993 +["Your avatar is a small photo, which will be shown always next to your name."] = "Dein Avatar ist ein kleines Bild, das überall neben deinem Namen angezeigt wird."; 303.994 +["Your choice"] = "Deine Auswahl"; 303.995 ["Your email address has been changed, please check for confirmation email with activation link!"] = "Deine E-Mail-Adresse wurde geändert, du hast eine Bestätigungs-E-Mail mit Aktivierungslink erhalten."; 303.996 ["Your login has been changed to '#{login}'"] = "Dein Anmeldename wurde auf '#{login}' geändert"; 303.997 ["Your name has been changed"] = "Dein Name wurde geändert"; 303.998 ["Your page has been updated"] = "Deine Seite wurde aktualisiert"; 303.999 ["Your password has been updated successfully"] = "Das Kennwort wurde erfolgreich geändert"; 303.1000 +["Your photo will be shown in your profile."] = "Dein Foto wird deinem Profil angezeigt"; 303.1001 ["Your rating has been deleted"] = "Deine Bewertung wurde gelöscht"; 303.1002 ["Your rating has been updated"] = "Deine Bewertung wurde aktualisiert"; 303.1003 ["Your request has been processed."] = "Die Anfrage wurde bearbeitet."; 303.1004 ["Your suggestion has been added"] = "Deine Anregung wurde hinzufügt"; 303.1005 -["Your support has been added to this initiative"] = "Deine Unterstützung wurde der Initiative hinzugefügt"; 303.1006 -["Your support has been removed from this initiative"] = "Deine Unterstützung wurde der Initiative entzogen"; 303.1007 ["Your support has been updated to the latest draft"] = "Deine Unterstützung wurde auf den neuesten Entwurf aktualisiert"; 303.1008 ["Your vote has been discarded. Delegation rules apply if set."] = "Deine Abstimmung wurde zurückgezogen. Delegationsregeln gelten sofern gesetzt."; 303.1009 ["Z-A"] = "Z-A"; 303.1010 ["[Name of Language]"] = "Deutsch"; 303.1011 ["[No voting privilege]"] = "[Kein Stimmrecht]"; 303.1012 ["[Registered members only]"] = "[nur für Registrierte]"; 303.1013 +["[calculating]"] = "[wird berechnet...]"; 303.1014 ["[event mail] URL: #{url}"] = " URL: #{url}"; 303.1015 -["[event mail] Area: #{name}"] = "Themengebiet: #{name}"; 303.1016 +["[event mail] Area: #{name}"] = "Themenbereich: #{name}"; 303.1017 ["[event mail] Unit: #{name}"] = " Gliederung: #{name}"; 303.1018 ["[event mail] Event: #{event}"] = " Ereignis: #{event}"; 303.1019 ["[event mail] Issue: ##{id}"] = " Thema: ##{id}"; 303.1020 @@ -741,15 +774,58 @@ 303.1021 ["[not displayed public]"] = "[nicht öffentlich]"; 303.1022 ["a bit unsatisfied"] = "etwas unzufrieden"; 303.1023 ["abandoned"] = "ausgesetzt"; 303.1024 +["accept invitation"] = "Einladung annehmen"; 303.1025 ["action"] = "Aktion"; 303.1026 +["activate account"] = "Konto aktivieren"; 303.1027 ["activated"] = "aktiviert"; 303.1028 +["add my interest"] = "Interesse anmelden"; 303.1029 +["add my support"] = "unterstützen"; 303.1030 +["add to my list of private contacts"] = "Zur meiner Kontaktliste hinzufügen"; 303.1031 +["add to my list of public contacts"] = "Zu meiner öffentlichen Kontaktliste hinzufügen"; 303.1032 +["add your support (see above) and rate or write new suggestions (and thereby restrict your support to certain conditions if necessary)"] = "Die Initiative untersützen (siehe oben) und Verbesserungsvorschläge bewerten oder machen (und dabei ggfs. die Unterstützung beschränken)"; 303.1033 +["all issues"] = "alle Themen"; 303.1034 +["allow invitation again"] = "Einladen wieder erlauben"; 303.1035 +["and"] = "und"; 303.1036 ["and #{count} more initiatives"] = "und #{count} weitere Initiativen"; 303.1037 -["and one more initiative"] = "und eine weitere Initiative"; 303.1038 -["area"] = "Themengebiet"; 303.1039 +["area"] = "Themenbereich"; 303.1040 ["at least #{count} approvals"] = "mindestens #{count} Zustimmungen"; 303.1041 ["at least #{count} approvals or abstentions"] = "mindestens #{count} Zustimmungen oder Enthaltungen"; 303.1042 -["change discussion URL"] = "Diskussions-URL ändern"; 303.1043 +["author"] = "Autor"; 303.1044 +["avatar/photo"] = "Avatar/Foto"; 303.1045 +["block this member"] = "Dieses Mitglied blocken"; 303.1046 +["browse through the competing initiatives"] = "durch die konkurrierenden Initiativen sehen"; 303.1047 +["but"] = "aber"; 303.1048 +["by default only those issues are shown, for which your are eligible to participate (change filters on top of the list)"] = "Standardmäßig werden nur die Themen angezeigt, für die du teilnahmeberechtigt bist, Filter können am Anfang der Liste angepasst werden"; 303.1049 +["cancel"] = "Abbrechen"; 303.1050 +["cancel issue"] = "Thema abbrechen"; 303.1051 +["cancel issue now"] = "Thema jetzt abbrechen"; 303.1052 +["cancel registration"] = "Registrierung abbrechen"; 303.1053 +["canceled"] = "abgebrochen"; 303.1054 +["change avatar/photo"] = "Avatar/Foto ändern"; 303.1055 +["change my vote"] = "Abstimmung ändern"; 303.1056 +["change vote"] = "Abstimmung ändern"; 303.1057 +["change your login"] = "Anmeldenamen ändern"; 303.1058 +["change your notification email address"] = "E-Mail-Adresse für Benachrichtigungen ändern"; 303.1059 +["change your password"] = "Kennwort ändern"; 303.1060 +["change your screen name"] = "Screen name ändern"; 303.1061 +["change/revoke area delegation"] = "Delegation für Themenbereich ändern/widerrufen"; 303.1062 +["change/revoke delegation"] = "Delegation ändern/widerrufen"; 303.1063 +["change/revoke delegation of organizational unit"] = "Delegation für Gliederung ändern/widerrufen"; 303.1064 +["change/revoke delegation of subject area"] = "Delegation für Themenbereich ändern/widerrufen"; 303.1065 +["change/revoke delegation only for this issue"] = "Delegation nur für dieses Thema ändern/widerrufen"; 303.1066 +["change/revoke delegation only for this subject area"] = "Delegation nur für diesen Themenbereich ändern/widerrufen"; 303.1067 +["change/revoke issue delegation"] = "Delegation für Thema ändern/widerrufen"; 303.1068 +["check your "] = "überprüfe die "; 303.1069 +["choose delegatee"] = "Delegierten auswählen"; 303.1070 +["choose issue delegatee"] = "Delegierten für Thema auswählen"; 303.1071 +["choose subject area delegatee"] = "Delegierten für Themenbereich auswählen"; 303.1072 +["collapse subject areas"] = "Themenbereiche einklappen"; 303.1073 +["collective rating:"] = "kollektive Bewertung:"; 303.1074 +["compare"] = "vergleichen"; 303.1075 +["compare revisions"] = "Revisionen vergleichen"; 303.1076 ["confirm"] = "bestätigen"; 303.1077 +["confirmed address"] = "bestätigte Adresse"; 303.1078 +["database download"] = "Datenbank herunterladen"; 303.1079 ["day [interval ago]"] = "Tag"; 303.1080 ["day [interval time left]"] = "Tag"; 303.1081 ["day [interval]"] = "Tag"; 303.1082 @@ -759,15 +835,47 @@ 303.1083 ["deactivated"] = "deaktiviert"; 303.1084 ["delegated to"] = "delegiert an"; 303.1085 ["delegates to"] = "delegiert an"; 303.1086 +["delegation suspended during discussion"] = "Delegation während der Diskussion ausgesetzt"; 303.1087 ["delete<br /><br />"] = "löschen<br /><br />"; 303.1088 -["disabled"] = "ausgeschaltet"; 303.1089 +["developer settings"] = "Einstellungen für Entwickler"; 303.1090 +["direct interest"] = "direktes Interesse"; 303.1091 +["discard"] = "verwerfen"; 303.1092 +["discard my vote"] = "Meine Stimme widerrufen"; 303.1093 +["do not notify me about this voting anymore"] = "über diese Abstimmung nicht mehr benachrichtigen"; 303.1094 +["draft ID"] = "Entwurf ID"; 303.1095 +["draft history (#{count})"] = "Entwurfshistorie (#{count})"; 303.1096 +["edit profile data"] = "Profildaten bearbeiten"; 303.1097 +["edit proposal and/or reasons"] = "Antrag und/oder Begründung bearbeiten"; 303.1098 ["email"] = "E-Mail"; 303.1099 +["ends in #{state_time_left}"] = "endet in #{state_time_left}"; 303.1100 +["ends soon"] = "endet bald"; 303.1101 +["failed #{quorum}"] = "#{quorum} nicht erreicht"; 303.1102 +["finished"] = "abgeschlossen"; 303.1103 ["global"] = "Global"; 303.1104 +["hide details"] = "Details ausblenden"; 303.1105 ["i#{id}: #{name}"] = false; 303.1106 +["if you like to implement a suggestion in your proposal and/or reasons, update your initiative draft"] = "um einen Verbesserungsvorschlag umzusetzen, den Entwurfstext der Initiative aktualisieren"; 303.1107 ["implemented"] = "umgesetzt"; 303.1108 +["implemented:"] = "umgesetzt:"; 303.1109 +["in all phases"] = "in allen Phasen"; 303.1110 +["in my areas"] = "in meinen Themenbereichen"; 303.1111 +["in my units"] = "in meinen Gliederungen"; 303.1112 ["inactive"] = "inaktiv"; 303.1113 -["last 24 hours"] = "letzte 24 Stunden"; 303.1114 +["initiated by me"] = "von mir initiiert"; 303.1115 +["interest via delegation"] = "Interesse per Delegation"; 303.1116 +["interested directly or via delegation"] = "Interesse per Delegation oder direkt"; 303.1117 +["invite another initiator"] = "weiteren Initiator einladen"; 303.1118 +["is implemented"] = "ist umgesetzt"; 303.1119 +["is not implemented"] = "ist nicht umgesetzt"; 303.1120 +["issue"] = "Thema"; 303.1121 +["issue view"] = "Themenansicht"; 303.1122 ["login name"] = "Anmeldename"; 303.1123 +["login to participate"] = "anmelden um teilzunehmen"; 303.1124 +["logout"] = "abmelden"; 303.1125 +["make this contact private"] = "diesen Kontakt nicht mehr öffentlich zeigen"; 303.1126 +["make this contact public"] = "diesen Kontakt öffentlich zeigen"; 303.1127 +["member"] = "Mitglied"; 303.1128 +["member inactive"] = "Mitglied inaktiv"; 303.1129 ["month [interval ago]"] = "Monat"; 303.1130 ["month [interval time left]"] = "Monat"; 303.1131 ["month [interval]"] = "Monat"; 303.1132 @@ -776,28 +884,102 @@ 303.1133 ["months [interval]"] = "Monate"; 303.1134 ["more unsatisfied"] = "sehr unzufrieden"; 303.1135 ["must"] = "muss"; 303.1136 +["must be implemented"] = "muß umgesetzt werden"; 303.1137 ["must not"] = "darf nicht"; 303.1138 +["my issues"] = "meine Themen"; 303.1139 ["neutral"] = "neutral"; 303.1140 ["no reverse beat path to status quo (including ties)"] = "Kein rückwärtsgerichteter Schlagpfad zum Status Quo (Gleichstände eingeschlossen)"; 303.1141 ["none"] = "kein"; 303.1142 +["not admitted"] = "nicht zugelassen"; 303.1143 ["not implemented"] = "nicht umgesetzt"; 303.1144 +["not voted by me"] = "nicht von mir abgestimmt"; 303.1145 ["not yet"] = "bis jetzt nicht"; 303.1146 +["notification settings"] = "Benachrichtigungseinstellungen"; 303.1147 +["notifications"] = "Benachrichtigungen"; 303.1148 +["notifications settings"] = "Benachrichtigungseinstellungen"; 303.1149 +["one step back"] = "einen Schritt zurück"; 303.1150 +["open the appropriate subject area for your issue and follow the instruction on that page."] = "öffne das passende Themenbereich für dein Thema und folge dort den Anweisungen"; 303.1151 +["open the organizational unit, subject area or issue you like to delegate and follow the instruction on that page."] = "öffne die Gliederung, den Themenbereich oder das Thema, das du delegieren möchtest und folge dort den Anweisungen"; 303.1152 +["or swipe"] = "oder swipen"; 303.1153 +["phase ends soon"] = "Phase endet bald"; 303.1154 ["possibly instable result caused by multistage majority"] = "Möglicherweise instabiles Ergebnis aufgrund mehrstufiger Mehrheiten"; 303.1155 +["preference voting"] = "Präferenzabstimmung"; 303.1156 +["proceed with registration"] = "Registrierung fortsetzen"; 303.1157 ["prohibit potentially instable results caused by multistage majorities"] = "Instabile Ergebnisse aufgrund mehrstufiger Mehrheiten verbieten"; 303.1158 +["public administrative notice:"] = "Öffentlicher administrativer Kommentar"; 303.1159 +["publish avatar/photo"] = "Avatar/Foto veröffentlichen"; 303.1160 +["publish my rating"] = "Wertung veröffentlichen"; 303.1161 +["publish profile data"] = "Profildaten veröffentlichen"; 303.1162 +["publish suggestion"] = "Verbesserungsvorschlag veröffentlichen"; 303.1163 +["published at"] = "veröffentlicht am/um"; 303.1164 +["reached #{quorum}"] = "#{quorum} erreicht"; 303.1165 +["refresh my support"] = "meine Unterstützung erneuern"; 303.1166 +["refuse invitation"] = "Einladung ablehnen"; 303.1167 +["remove an initiator"] = "Initiator entfernen"; 303.1168 +["remove from my contact list"] = "aus meiner Kontaktliste entfernen"; 303.1169 +["remove my interest"] = "Interesse abmelden"; 303.1170 +["remove my support"] = "Unterstützung widerrufen"; 303.1171 ["reverse beat path to status quo (including ties)"] = "Rückwärtsgerichteter Schlagpfad zum Status Quo (Gleichstände eingeschlossen)"; 303.1172 ["revoke"] = "zurückziehen"; 303.1173 +["revoke initiative"] = "Initiative zurückziehen"; 303.1174 +["revoked"] = "zurückgezogen"; 303.1175 ["satisfied"] = "zufrieden"; 303.1176 +["search"] = "suchen"; 303.1177 +["select tabs"] = "Andere Tabs auswählen"; 303.1178 ["should"] = "soll"; 303.1179 +["should be implemented"] = "soll umgesetzt werden"; 303.1180 ["should not"] = "soll nicht"; 303.1181 +["show all units"] = "Alle Gliederungen anzeigen"; 303.1182 +["show details"] = "Details anzeigen"; 303.1183 +["show differences"] = "Unterschiede anzeigen"; 303.1184 +["show other subject areas"] = "andere Themenbereiche anzeigen"; 303.1185 +["show saved contacts"] = "Gespeicherte Kontakte anzeigen"; 303.1186 +["show subject areas"] = "Themenbereiche anzeigen"; 303.1187 +["show vote"] = "Stimmzettel anzeigen"; 303.1188 +["start a new competing initiative"] = "eine neue konkurrierende Initiative starten"; 303.1189 +["start an initiative in a new issue"] = "eine Initiative in einem neuen Thema starten"; 303.1190 +["structured discussion"] = "strukturierte Diskussion"; 303.1191 +["subscribe"] = "Interesse anmelden"; 303.1192 +["subscribe subject areas or add your interested to issues and you will be notified about changes (follow the instruction on the area or issue page)"] = "Melde dich für Themenbereiche an oder interessiere dich für Themen, damit du benachrichtigst wird (folge den Anweisungen auf der Themenbereichs- bzw. Themenseite)"; 303.1193 +["subscribed"] = "am Themenbereich angemeldet"; 303.1194 +["suggestions (#{count}) ↓"] = "Verbesserungsvorschläge (#{count}) ↓"; 303.1195 +["supporter"] = "Unterstützer"; 303.1196 +["supporter with restricting suggestions"] = "Unterstützer mit beschränkenden Verbesserungsvorschlägen"; 303.1197 +["take a look at the competing initiatives"] = "schau dir die konkurrierenden Initiativen an"; 303.1198 +["take a look at the suggestions (see left) and rate them"] = "schau dir die Anregungen (links) an und bewerte sie"; 303.1199 +["take a look at the suggestions of your supporters"] = "schau die die Anregungen deiner Unterstützer an"; 303.1200 +["take a look on the issues (see left)"] = "schau dir die Themen an (siehe links)"; 303.1201 ["the following login is connected to this email address:\n\n"] = "der folgende Anmeldename ist mit dieser E-Mail-Adresse verknüpft:\n\n"; 303.1202 +["this issue is in verification phase, therefore the initiative text cannot be updated anymore"] = "dieses Thema ist in der Überprüfungsphase, daher kann der Text nicht mehr geändert werden"; 303.1203 +["this issue is in voting phase, therefore the initiative text cannot be updated anymore"] = "dieses Thema ist in Abstimmung, daher kann der Text nicht mehr geändert werden"; 303.1204 +["timeline"] = "Zeitlicher Verlauf"; 303.1205 +["to argue about suggestions, just add your arguments to your reasons in the initiative draft, so your supporters can learn about your opinion"] = "um Verbesserungsvorschlägen zu kommentieren, füge deine Argumente in den Text deiner Initiative ein, damit deine Untersützer deine Position verstehen können"; 303.1206 ["to reset your password please click on the following link:\n\n"] = "um Dein Kennwort zurückzusetzen klicke bitte den folgenden Link an:\n\n"; 303.1207 +["to show more info and learn what you can do"] = "für mehr Infos und 'Was kann ich tun?'"; 303.1208 +["today at #{time}"] = "heute um #{time}"; 303.1209 +["unblock member"] = "Blockierung aufheben"; 303.1210 +["unconfirmed address"] = "unbestätigte Adresse"; 303.1211 ["unit"] = "Gliederung"; 303.1212 -["unit / area"] = "Gliederung / Themengebiet"; 303.1213 +["unit / area"] = "Gliederung / Themenbereich"; 303.1214 +["unsubscribe"] = "Interesse abmelden"; 303.1215 ["until"] = "bis"; 303.1216 +["update area"] = "Themenbereich aktualisiern"; 303.1217 +["update member"] = "Mitglied aktualisieren"; 303.1218 +["update policy"] = "Regelwerk aktualisieren"; 303.1219 +["update unit"] = "Gliederung aktualisieren"; 303.1220 ["variable"] = "variabel"; 303.1221 -["with winner"] = "mit Gewinner"; 303.1222 +["via delegation"] = "per Delegation"; 303.1223 +["vote delegation"] = "Stimmdelegation"; 303.1224 +["vote now"] = "jetzt abstimmen"; 303.1225 +["voted and not voted by me"] = "von mir abgestimmt und nicht abgestimmt"; 303.1226 +["voted by me"] = "von mir abgestimmt"; 303.1227 +["voted directly by me"] = "von mir direkt abgestimmt"; 303.1228 +["voted no"] = "mit Nein gestimmt"; 303.1229 +["voted via delegation"] = "von mir per Delegation abgestimmt"; 303.1230 +["voted yes"] = "mit Ja gestimmt"; 303.1231 ["without"] = "ohne"; 303.1232 -["without winner"] = "ohne Gewinner"; 303.1233 +["write a new suggestion"] = "neuen Verbesserungsvorschlag einbringen"; 303.1234 +["written and rated by the supportes of this initiative to improve the proposal and its reasons"] = "geschrieben und bewertet von Unterstützern dieser Initiative"; 303.1235 ["xmpp"] = "Jabber (XMPP)"; 303.1236 ["year [interval ago]"] = "Jahr"; 303.1237 ["year [interval time left]"] = "Jahr"; 303.1238 @@ -805,4 +987,10 @@ 303.1239 ["years [interval ago]"] = "Jahren"; 303.1240 ["years [interval time left]"] = "Jahre"; 303.1241 ["years [interval]"] = "Jahre"; 303.1242 +["yesterday at #{time}"] = "gestern um #{time}"; 303.1243 +["you are interested"] = "du bist interessiert"; 303.1244 +["you are subscribed"] = "du bist am Themembreich angemeldet"; 303.1245 +["you have #{count} incoming delegations"] = "#{count} eingehende Delegationen"; 303.1246 +["you restricted your support by rating suggestions as must or must not"] = "deine Untersützung ist aufgrund von 'muss'- oder 'darf nicht'-Anregungen beschränkt"; 303.1247 +["you voted"] = "du hast abgestimmt"; 303.1248 }
304.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 304.2 +++ b/model/battle.lua Thu Jul 10 01:19:48 2014 +0200 304.3 @@ -0,0 +1,10 @@ 304.4 +Battle = mondelefant.new_class() 304.5 +Battle.table = 'battle' 304.6 + 304.7 +function Battle:getByInitiativeIds(winning_id, losing_id) 304.8 + local selector = Battle:new_selector() 304.9 + selector:add_where { "winning_initiative_id = ?", winning_id } 304.10 + selector:add_where { "losing_initiative_id = ?", losing_id } 304.11 + selector:optional_object_mode() 304.12 + return selector:exec() 304.13 +end
305.1 --- a/model/contact.lua Thu Jul 10 01:02:43 2014 +0200 305.2 +++ b/model/contact.lua Thu Jul 10 01:19:48 2014 +0200 305.3 @@ -33,6 +33,9 @@ 305.4 if args.member_id then 305.5 selector:add_where{ "member_id = ?", args.member_id } 305.6 end 305.7 + if args.public ~= nil then 305.8 + selector:add_where{ "public = ?", args.public } 305.9 + end 305.10 if args.order then 305.11 if args.order == "name" then 305.12 selector:add_order_by("member.name")
306.1 --- a/model/initiative.lua Thu Jul 10 01:02:43 2014 +0200 306.2 +++ b/model/initiative.lua Thu Jul 10 01:19:48 2014 +0200 306.3 @@ -10,6 +10,14 @@ 306.4 } 306.5 306.6 Initiative:add_reference{ 306.7 + mode = 'm1', 306.8 + to = "Member", 306.9 + this_key = 'revoked_by_member_id', 306.10 + that_key = 'id', 306.11 + ref = 'revoked_by_member', 306.12 +} 306.13 + 306.14 +Initiative:add_reference{ 306.15 mode = '1m', 306.16 to = "Draft", 306.17 this_key = 'id', 306.18 @@ -26,6 +34,7 @@ 306.19 that_key = 'initiative_id', 306.20 ref = 'suggestions', 306.21 back_ref = 'initiative', 306.22 + default_order = '"proportional_order" NULLS LAST, id' 306.23 } 306.24 306.25 Initiative:add_reference{ 306.26 @@ -223,6 +232,61 @@ 306.27 :add_where("initiative.revoked ISNULL") 306.28 end 306.29 306.30 +function Initiative:getSpecialSelector( args ) 306.31 + local selector = Initiative:new_selector() 306.32 + selector:join( "issue", nil, "issue.id = initiative.issue_id" ) 306.33 + selector:join( "area", nil, "area.id = issue.area_id" ) 306.34 + if args.area_id then 306.35 + selector:add_where{ "area.id = ?", args.area_id } 306.36 + elseif args.unit_id then 306.37 + selector:add_where{ "area.unit_id = ?", args.unit_id } 306.38 + end 306.39 + selector:limit( 1 ) 306.40 + selector:optional_object_mode() 306.41 + return selector 306.42 +end 306.43 + 306.44 +function Initiative:getLastWinner( args ) 306.45 + local selector = Initiative:getSpecialSelector( args ) 306.46 + selector:add_where( "issue.state = 'finished_with_winner'" ) 306.47 + selector:add_order_by( "issue.closed DESC, id DESC" ) 306.48 + return selector:exec() 306.49 +end 306.50 + 306.51 +function Initiative:getLastLoser( args ) 306.52 + local selector = Initiative:getSpecialSelector( args ) 306.53 + selector:add_where( "issue.state = 'finished_without_winner'" ) 306.54 + selector:add_order_by( "issue.closed DESC, id DESC" ) 306.55 + return selector:exec() 306.56 +end 306.57 + 306.58 +function Initiative:getNextEndingVoting( args ) 306.59 + local selector = Initiative:getSpecialSelector( args ) 306.60 + selector:add_where( "issue.state = 'voting'" ) 306.61 + selector:add_order_by( "issue.fully_frozen + issue.verification_time DESC, id DESC" ) 306.62 + return selector:exec() 306.63 +end 306.64 + 306.65 +function Initiative:getNextEndingVerification( args ) 306.66 + local selector = Initiative:getSpecialSelector( args ) 306.67 + selector:add_where( "issue.state = 'verification'" ) 306.68 + selector:add_order_by( "issue.half_frozen + issue.verification_time DESC, id DESC" ) 306.69 + return selector:exec() 306.70 +end 306.71 + 306.72 +function Initiative:getNextEndingDiscussion( args ) 306.73 + local selector = Initiative:getSpecialSelector( args ) 306.74 + selector:add_where( "issue.state = 'discussion'" ) 306.75 + selector:add_order_by( "issue.accepted + issue.discussion_time DESC, id DESC" ) 306.76 + return selector:exec() 306.77 +end 306.78 + 306.79 +function Initiative:getBestInAdmission( args ) 306.80 + local selector = Initiative:getSpecialSelector( args ) 306.81 + selector:add_where( "issue.state = 'admission'" ) 306.82 + selector:add_order_by( "issue.created + issue.admission_time DESC, id DESC" ) 306.83 + return selector:exec() 306.84 +end 306.85 306.86 function Initiative.object_get:current_draft() 306.87 return Draft:new_selector() 306.88 @@ -240,6 +304,10 @@ 306.89 return name 306.90 end 306.91 306.92 +function Initiative.object_get:display_name() 306.93 + return "i" .. self.id .. ": " .. self.name 306.94 +end 306.95 + 306.96 function Initiative.object_get:initiator_names() 306.97 local members = Member:new_selector() 306.98 :join("initiator", nil, "initiator.member_id = member.id") 306.99 @@ -254,3 +322,8 @@ 306.100 return member_names 306.101 end 306.102 306.103 +function Initiative.object_get:potential_supporter_count() 306.104 + if self.supporter_count and self.satisfied_supporter_count then 306.105 + return self.supporter_count - self.satisfied_supporter_count 306.106 + end 306.107 +end
307.1 --- a/model/issue.lua Thu Jul 10 01:02:43 2014 +0200 307.2 +++ b/model/issue.lua Thu Jul 10 01:19:48 2014 +0200 307.3 @@ -142,23 +142,29 @@ 307.4 if #ids == 0 then 307.5 return sub_selector:empty_list_mode() 307.6 end 307.7 - sub_selector:from("issue") 307.8 - sub_selector:add_field("issue.id", "issue_id") 307.9 - sub_selector:add_field{ '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id } 307.10 - sub_selector:add_where{ 'issue.id IN ($)', ids } 307.11 + sub_selector:from ( "issue" ) 307.12 + sub_selector:add_field ( "issue.id", "issue_id" ) 307.13 + sub_selector:add_field { '(delegation_info(?, null, null, issue.id, ?)).*', options.member_id, options.trustee_id } 307.14 + sub_selector:add_where { 'issue.id IN ($)', ids } 307.15 307.16 local selector = Issue:get_db_conn():new_selector() 307.17 - selector:add_from("issue") 307.18 - selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id") 307.19 - selector:left_join("member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id") 307.20 - selector:left_join("member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id") 307.21 - selector:add_field("delegation_info.*") 307.22 - selector:add_field("first_trustee.name", "first_trustee_name") 307.23 - selector:add_field("other_trustee.name", "other_trustee_name") 307.24 - selector:left_join("direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id }) 307.25 - selector:add_field("direct_voter.member_id NOTNULL", "direct_voted") 307.26 - selector:left_join("non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", options.member_id }) 307.27 - selector:add_field("non_voter.member_id NOTNULL", "non_voter") 307.28 + selector:add_from ( "issue" ) 307.29 + selector:join(sub_selector, "delegation_info", "delegation_info.issue_id = issue.id" ) 307.30 + selector:left_join ( "member", "first_trustee", "first_trustee.id = delegation_info.first_trustee_id" ) 307.31 + selector:left_join ( "member", "other_trustee", "other_trustee.id = delegation_info.other_trustee_id" ) 307.32 + selector:add_field ( "delegation_info.*" ) 307.33 + selector:add_field ( "first_trustee.name", "first_trustee_name" ) 307.34 + selector:add_field ( "other_trustee.name", "other_trustee_name" ) 307.35 + selector:left_join ( "direct_voter", nil, { "direct_voter.issue_id = issue.id AND direct_voter.member_id = ?", options.member_id }) 307.36 + selector:add_field ( "direct_voter.member_id NOTNULL", "direct_voted") 307.37 + selector:left_join ( "non_voter", nil, { "non_voter.issue_id = issue.id AND non_voter.member_id = ?", options.member_id }) 307.38 + selector:add_field ( "non_voter.member_id NOTNULL", "non_voter" ) 307.39 + selector:left_join ( "direct_interest_snapshot", nil, { [[ 307.40 + direct_interest_snapshot.issue_id = issue.id AND 307.41 + direct_interest_snapshot.event = issue.latest_snapshot_event AND 307.42 + direct_interest_snapshot.member_id = ? 307.43 + ]], options.member_id }) 307.44 + selector:add_field ( "direct_interest_snapshot.weight", "weight" ) 307.45 return selector 307.46 end 307.47 } 307.48 @@ -189,19 +195,19 @@ 307.49 307.50 function Issue:get_state_name_for_state(value) 307.51 local state_name_table = { 307.52 - admission = _"New", 307.53 + admission = _"Admission", 307.54 discussion = _"Discussion", 307.55 - verification = _"Frozen", 307.56 + verification = _"Verification", 307.57 voting = _"Voting", 307.58 - canceled_revoked_before_accepted = _"Canceled (before accepted due to revocation)", 307.59 - canceled_issue_not_accepted = _"Canceled (issue not accepted)", 307.60 - canceled_after_revocation_during_discussion = _"Canceled (during discussion due to revocation)", 307.61 - canceled_after_revocation_during_verification = _"Canceled (during verification due to revocation)", 307.62 + canceled_revoked_before_accepted = _"Revoked (during admission)", 307.63 + canceled_issue_not_accepted = _"Failed 1st quorum", 307.64 + canceled_after_revocation_during_discussion = _"Revoked (during discussion)", 307.65 + canceled_after_revocation_during_verification = _"Revoked (during verification)", 307.66 canceled_by_admin = _"Canceled by administrative intervention", 307.67 calculation = _"Calculation", 307.68 - canceled_no_initiative_admitted = _"Canceled (no initiative admitted)", 307.69 - finished_without_winner = _"Finished (without winner)", 307.70 - finished_with_winner = _"Finished (with winner)", 307.71 + canceled_no_initiative_admitted = _"All initiatives failed 2nd quorum", 307.72 + finished_without_winner = _"Disapproved", 307.73 + finished_with_winner = _"Finished with winner", 307.74 } 307.75 return state_name_table[value] or value or '' 307.76 end 307.77 @@ -275,3 +281,17 @@ 307.78 function Issue.object_get:etherpad_url() 307.79 return config.etherpad.base_url .. "p/" .. config.etherpad.group_id .. "$Issue" .. self.id 307.80 end 307.81 + 307.82 +function Issue.object_get:name() 307.83 + return self.policy.name .. " #" .. self.id 307.84 +end 307.85 + 307.86 +function Issue.object_get:state_time_text() 307.87 + if self.closed then 307.88 + return _("#{closed_ago} ago", { closed_ago = self.closed_ago }) 307.89 + elseif string.sub(self.state_time_left, 1, 2) ~= "-" then 307.90 + return _("ends soon", { state_time_left = self.state_time_left }) 307.91 + else 307.92 + return _("ends in #{state_time_left}", { state_time_left = self.state_time_left }) 307.93 + end 307.94 +end
308.1 --- a/model/member.lua Thu Jul 10 01:02:43 2014 +0200 308.2 +++ b/model/member.lua Thu Jul 10 01:19:48 2014 +0200 308.3 @@ -124,7 +124,7 @@ 308.4 that_key = 'truster_id', 308.5 ref = 'outgoing_delegations', 308.6 back_ref = 'truster', 308.7 - default_order = '"id"' 308.8 +-- default_order = '"id"' 308.9 } 308.10 308.11 Member:add_reference{ 308.12 @@ -134,7 +134,7 @@ 308.13 that_key = 'trustee_id', 308.14 ref = 'incoming_delegations', 308.15 back_ref = 'trustee', 308.16 - default_order = '"id"' 308.17 +-- default_order = '"id"' 308.18 } 308.19 308.20 Member:add_reference{
309.1 Binary file static/back.png has changed
310.1 Binary file static/back50.png has changed
311.1 Binary file static/icons/16/chart_organisation.png has changed
312.1 Binary file static/icons/32/empty.png has changed
313.1 Binary file static/icons/32/phase_current.png has changed
314.1 Binary file static/icons/32/phase_failed.png has changed
315.1 Binary file static/icons/32/phase_finished.png has changed
316.1 Binary file static/icons/32/support_none.png has changed
317.1 Binary file static/icons/32/support_satisfied.png has changed
318.1 Binary file static/icons/32/support_satisfied_via_delegation.png has changed
319.1 Binary file static/icons/32/support_unsatisfied.png has changed
320.1 Binary file static/icons/32/support_unsatisfied_via_delegation.png has changed
321.1 Binary file static/icons/32/voted_no.png has changed
322.1 Binary file static/icons/48/bell.png has changed
323.1 Binary file static/icons/48/eye.png has changed
324.1 Binary file static/icons/48/home.png has changed
325.1 Binary file static/icons/48/info.png has changed
326.1 Binary file static/icons/48/lf_plus.png has changed
327.1 Binary file static/icons/48/star.png has changed
328.1 Binary file static/icons/48/star_empty.png has changed
329.1 Binary file static/icons/48/voted_ok.png has changed
330.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 330.2 +++ b/static/js/less-1.4.1.min.js Thu Jul 10 01:19:48 2014 +0200 330.3 @@ -0,0 +1,11 @@ 330.4 +/* 330.5 + * LESS - Leaner CSS v1.4.1 330.6 + * http://lesscss.org 330.7 + * 330.8 + * Copyright (c) 2009-2013, Alexis Sellier 330.9 + * Licensed under the Apache 2.0 License. 330.10 + * 330.11 + * @licence 330.12 + */(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,i,s){e?k(e,i.href):t&&S(t.toCSS(r),i,s.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)if(e[t].type.match(p)){var n=new r.tree.parseEnv(r);n.filename=document.location.href.replace(/#.*$/,""),(new r.Parser(n)).parse(e[t].innerHTML||"",function(n,i){if(n)return k(n,"inline");var s=i.toCSS(r),o=e[t];o.type="text/css",o.styleSheet?o.styleSheet.cssText=s:o.innerHTML=s})}}function g(e,t){for(var n=0;n<r.sheets.length;n++)w(r.sheets[n],e,t,r.sheets.length-(n+1))}function y(e,t){var n=b(e),r=b(t),i,s,o,u,a="";if(n.hostPart!==r.hostPart)return"";s=Math.max(r.directories.length,n.directories.length);for(i=0;i<s;i++)if(r.directories[i]!==n.directories[i])break;u=r.directories.slice(i),o=n.directories.slice(i);for(i=0;i<u.length-1;i++)a+="../";for(i=0;i<o.length-1;i++)a+=o[i]+"/";return a}function b(e,t){var n=/^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,r=e.match(n),i={},s=[],o,u;if(!r)throw new Error("Could not parse sheet href - '"+e+"'");if(!r[1]||r[2]){u=t.match(n);if(!u)throw new Error("Could not parse page url - '"+t+"'");r[1]=r[1]||u[1]||"",r[2]||(r[3]=u[3]+r[3])}if(r[3]){s=r[3].replace("\\","/").split("/");for(o=0;o<s.length;o++)s[o]==="."&&(s.splice(o,1),o-=1);for(o=0;o<s.length;o++)s[o]===".."&&o>0&&(s.splice(o-1,2),o-=2)}return i.hostPart=r[1],i.directories=s,i.path=r[1]+s.join("/"),i.fileUrl=i.path+(r[4]||""),i.url=i.fileUrl+(r[5]||""),i}function w(t,n,i,s){var o=b(t.href,e.location.href),u=o.url,a=l&&l.getItem(u),f=l&&l.getItem(u+":timestamp"),c={css:a,timestamp:f},h,p={relativeUrls:r.relativeUrls,currentDirectory:o.path,filename:u};t instanceof r.tree.parseEnv?(h=new r.tree.parseEnv(t),p.entryPath=h.currentFileInfo.entryPath,p.rootpath=h.currentFileInfo.rootpath,p.rootFilename=h.currentFileInfo.rootFilename):(h=new r.tree.parseEnv(r),h.mime=t.type,p.entryPath=o.path,p.rootpath=r.rootpath||o.path,p.rootFilename=u),h.relativeUrls&&(r.rootpath?p.rootpath=b(r.rootpath+y(o.path,p.entryPath)).path:p.rootpath=o.path),x(u,t.type,function(e,a){v+=e.replace(/@import .+?;/ig,"");if(!i&&c&&a&&(new Date(a)).valueOf()===(new Date(c.timestamp)).valueOf())S(c.css,t),n(null,null,e,t,{local:!0,remaining:s},u);else try{h.contents[u]=e,h.paths=[o.path],h.currentFileInfo=p,(new r.Parser(h)).parse(e,function(r,i){if(r)return n(r,null,null,t);try{n(r,i,e,t,{local:!1,lastModified:a,remaining:s},u),h.currentFileInfo.rootFilename===u&&N(document.getElementById("less-error-message:"+E(u)))}catch(r){n(r,null,null,t)}})}catch(f){n(f,null,null,t)}},function(e,r){n({type:"File",message:"'"+r+"' wasn't found ("+e+")"},null,null,t)})}function E(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function S(e,t,n){var r=t.href||"",i="less:"+(t.title||E(r)),s=document.getElementById(i),o=!1,u=document.createElement("style");u.setAttribute("type","text/css"),t.media&&u.setAttribute("media",t.media),u.id=i;if(u.styleSheet)try{u.styleSheet.cssText=e}catch(a){throw new Error("Couldn't reassign styleSheet.cssText.")}else u.appendChild(document.createTextNode(e)),o=s!==null&&s.childNodes.length>0&&u.childNodes.length>0&&s.firstChild.nodeValue===u.firstChild.nodeValue;var f=document.getElementsByTagName("head")[0];if(s==null||o===!1){var c=t&&t.nextSibling||null;(c||document.getElementsByTagName("head")[0]).parentNode.insertBefore(u,c)}s&&o===!1&&f.removeChild(s);if(n&&l){C("saving "+r+" to cache.");try{l.setItem(r,e),l.setItem(r+":timestamp",n)}catch(a){C("failed to save")}}}function x(e,t,n,i){function a(t,n,r){t.status>=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):typeof r=="function"&&r(t.status,e)}var s=T(),u=o?r.fileAsync:r.async;typeof s.overrideMimeType=="function"&&s.overrideMimeType("text/css"),s.open("GET",e,u),s.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),s.send(null),o&&!r.fileAsync?s.status===0||s.status>=200&&s.status<300?n(s.responseText):i(s.status,e):u?s.onreadystatechange=function(){s.readyState==4&&a(s,n,i)}:a(s,n,i)}function T(){if(e.XMLHttpRequest)return new XMLHttpRequest;try{return new ActiveXObject("MSXML2.XMLHTTP.3.0")}catch(t){return C("browser doesn't support AJAX."),null}}function N(e){return e&&e.parentNode.removeChild(e)}function C(e){r.env=="development"&&typeof console!="undefined"&&console.log("less: "+e)}function k(e,n){var i="less-error-message:"+E(n||""),s='<li><label>{line}</label><pre class="{class}">{content}</pre></li>',o=document.createElement("div"),u,a,f=[],l=e.filename||n,c=l.match(/([^\/]+(\?.*)?)$/)[1];o.id=i,o.className="less-error-message",a="<h3>"+(e.type||"Syntax")+"Error: "+(e.message||"There is an error in your .less file")+"</h3>"+'<p>in <a href="'+l+'">'+c+"</a> ";var h=function(e,n,r){e.extract[n]!=t&&f.push(s.replace(/\{line\}/,(parseInt(e.line)||0)+(n-1)).replace(/\{class\}/,r).replace(/\{content\}/,e.extract[n]))};e.extract?(h(e,0,""),h(e,1,"line"),h(e,2,""),a+="on line "+e.line+", column "+(e.column+1)+":</p>"+"<ul>"+f.join("")+"</ul>"):e.stack&&(a+="<br/>"+e.stack.split("\n").slice(1).join("<br/>")),o.innerHTML=a,S([".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),o.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),r.env=="development"&&(u=setInterval(function(){document.body&&(document.getElementById(i)?document.body.replaceChild(o,document.getElementById(i)):document.body.insertBefore(o,document.body.firstChild),clearInterval(u))},10))}var r,i,s;typeof environment=="object"&&{}.toString.call(environment)==="[object Environment]"?(typeof e=="undefined"?r={}:r=e.less={},i=r.tree={},r.mode="rhino"):typeof e=="undefined"?(r=exports,i=n("./tree"),r.mode="node"):(typeof e.less=="undefined"&&(e.less={}),r=e.less,i=e.less.tree={},r.mode="browser"),r.Parser=function(t){function m(){a=c[u],f=o,h=o}function g(){c[u]=a,o=f,h=o}function y(){o>h&&(c[u]=c[u].slice(o-h),h=o)}function b(e){var t=e.charCodeAt(0);return t===32||t===10||t===9}function w(e){var t,n,r,i,a;if(e instanceof Function)return e.call(p.parsers);if(typeof e=="string")t=s.charAt(o)===e?e:null,r=1,y();else{y();if(!(t=e.exec(c[u])))return null;r=t[0].length}if(t)return E(r),typeof t=="string"?t:t.length===1?t[0]:t}function E(e){var t=o,n=u,r=o+c[u].length,i=o+=e;while(o<r){if(!b(s.charAt(o)))break;o++}return c[u]=c[u].slice(e+(o-i)),h=o,c[u].length===0&&u<c.length-1&&u++,t!==o||n!==u}function S(e,t){var n=w(e);if(!!n)return n;x(t||(typeof e=="string"?"expected '"+e+"' got '"+s.charAt(o)+"'":"unexpected token"))}function x(e,t){var n=new Error(e);throw n.index=o,n.type=t||"Syntax",n}function T(e){return typeof e=="string"?s.charAt(o)===e:e.test(c[u])?!0:!1}function N(e,t){return e.filename&&t.currentFileInfo.filename&&e.filename!==t.currentFileInfo.filename?p.imports.contents[e.filename]:s}function C(e,t){for(var n=e,r=-1;n>=0&&t.charAt(n)!=="\n";n--)r++;return{line:typeof e=="number"?(t.slice(0,e).match(/\n/g)||"").length:null,column:r}}function k(e,t,i){var s=i.currentFileInfo.filename;return r.mode!=="browser"&&r.mode!=="rhino"&&(s=n("path").resolve(s)),{lineNumber:C(e,t).line+1,fileName:s}}function L(e,t){var n=N(e,t),r=C(e.index,n),i=r.line,s=r.column,o=n.split("\n");this.type=e.type||"Syntax",this.message=e.message,this.filename=e.filename||t.currentFileInfo.filename,this.index=e.index,this.line=typeof i=="number"?i+1:null,this.callLine=e.call&&C(e.call,n).line+1,this.callExtract=o[C(e.call,n).line],this.stack=e.stack,this.column=s,this.extract=[o[i-1],o[i],o[i+1]]}var s,o,u,a,f,l,c,h,p,d=this;t instanceof i.parseEnv||(t=new i.parseEnv(t));var v=this.imports={paths:t.paths||[],queue:[],files:t.files,contents:t.contents,mime:t.mime,error:null,push:function(e,n,i){var s=this;this.queue.push(e),r.Parser.importer(e,n,function(t,n,r){s.queue.splice(s.queue.indexOf(e),1);var o=r in s.files;s.files[r]=n,t&&!s.error&&(s.error=t),i(t,n,o)},t)}};return L.prototype=new Error,L.prototype.constructor=L,this.env=t=t||{},this.optimization="optimization"in this.env?this.env.optimization:1,p={imports:v,parse:function(e,a){var f,d,v,m,g,y,b=[],E,S=null;o=u=h=l=0,s=e.replace(/\r\n/g,"\n"),s=s.replace(/^\uFEFF/,""),c=function(e){var n=0,r=/(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,i=/\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,o=/"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,u=0,a,f=e[0],l;for(var c=0,h,p;c<s.length;){r.lastIndex=c,(a=r.exec(s))&&a.index===c&&(c+=a[0].length,f.push(a[0])),h=s.charAt(c),i.lastIndex=o.lastIndex=c;if(a=o.exec(s))if(a.index===c){c+=a[0].length,f.push(a[0]);continue}if(!l&&h==="/"){p=s.charAt(c+1);if(p==="/"||p==="*")if(a=i.exec(s))if(a.index===c){c+=a[0].length,f.push(a[0]);continue}}switch(h){case"{":if(!l){u++,f.push(h);break};case"}":if(!l){u--,f.push(h),e[++n]=f=[];break};case"(":if(!l){l=!0,f.push(h);break};case")":if(l){l=!1,f.push(h);break};default:f.push(h)}c++}return u!=0&&(S=new L({index:c-1,type:"Parse",message:u>0?"missing closing `}`":"missing opening `{`",filename:t.currentFileInfo.filename},t)),e.map(function(e){return e.join("")})}([[]]);if(S)return a(new L(S,t));try{f=new i.Ruleset([],w(this.parsers.primary)),f.root=!0,f.firstRoot=!0}catch(x){return a(new L(x,t))}f.toCSS=function(e){var s,o,u;return function(s,o){s=s||{};var u,a=new i.evalEnv(s);typeof o=="object"&&!Array.isArray(o)&&(o=Object.keys(o).map(function(e){var t=o[e];return t instanceof i.Value||(t instanceof i.Expression||(t=new i.Expression([t])),t=new i.Value([t])),new i.Rule("@"+e,t,!1,0)}),a.frames=[new i.Ruleset(null,o)]);try{var f=e.call(this,a);(new i.joinSelectorVisitor).run(f),(new i.processExtendsVisitor).run(f);var l=f.toCSS({compress:Boolean(s.compress),dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(s.strictUnits)})}catch(c){throw new L(c,t)}return s.yuicompress&&r.mode==="node"?n("ycssmin").cssmin(l,s.maxLineLen):s.compress?l.replace(/(\s)+/g,"$1"):l}}(f.eval);if(o<s.length-1){o=l,y=s.split("\n"),g=(s.slice(0,o).match(/\n/g)||"").length+1;for(var T=o,N=-1;T>=0&&s.charAt(T)!=="\n";T--)N++;S={type:"Parse",message:"Unrecognised input",index:o,filename:t.currentFileInfo.filename,line:g,column:N,extract:[y[g-2],y[g-1],y[g]]}}var C=function(e){e=S||e||p.imports.error,e?(e instanceof L||(e=new L(e,t)),a(e)):a(null,f)};t.processImports!==!1?(new i.importVisitor(this.imports,C)).run(f):C()},parsers:{primary:function(){var e,t=[];while((e=w(this.extendRule)||w(this.mixin.definition)||w(this.rule)||w(this.ruleset)||w(this.mixin.call)||w(this.comment)||w(this.directive))||w(/^[\s\n]+/)||w(/^;+/))e&&t.push(e);return t},comment:function(){var e;if(s.charAt(o)!=="/")return;if(s.charAt(o+1)==="/")return new i.Comment(w(/^\/\/.*/),!0);if(e=w(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/))return new i.Comment(e)},entities:{quoted:function(){var e,n=o,r,u=o;s.charAt(n)==="~"&&(n++,r=!0);if(s.charAt(n)!=='"'&&s.charAt(n)!=="'")return;r&&w("~");if(e=w(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/))return new i.Quoted(e[0],e[1]||e[2],r,u,t.currentFileInfo)},keyword:function(){var e;if(e=w(/^[_A-Za-z-][_A-Za-z0-9-]*/))return i.colors.hasOwnProperty(e)?new i.Color(i.colors[e].slice(1)):new i.Keyword(e)},call:function(){var e,n,r,s,a=o;if(!(e=/^([\w-]+|%|progid:[\w\.]+)\(/.exec(c[u])))return;e=e[1],n=e.toLowerCase();if(n==="url")return null;o+=e.length;if(n==="alpha"){s=w(this.alpha);if(typeof s!="undefined")return s}w("("),r=w(this.entities.arguments);if(!w(")"))return;if(e)return new i.Call(e,r,a,t.currentFileInfo)},arguments:function(){var e=[],t;while(t=w(this.entities.assignment)||w(this.expression)){e.push(t);if(!w(","))break}return e},literal:function(){return w(this.entities.dimension)||w(this.entities.color)||w(this.entities.quoted)||w(this.entities.unicodeDescriptor)},assignment:function(){var e,t;if((e=w(/^\w+(?=\s?=)/i))&&w("=")&&(t=w(this.entity)))return new i.Assignment(e,t)},url:function(){var e;if(s.charAt(o)!=="u"||!w(/^url\(/))return;return e=w(this.entities.quoted)||w(this.entities.variable)||w(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/)||"",S(")"),new i.URL(e.value!=null||e instanceof i.Variable?e:new i.Anonymous(e),t.currentFileInfo)},variable:function(){var e,n=o;if(s.charAt(o)==="@"&&(e=w(/^@@?[\w-]+/)))return new i.Variable(e,n,t.currentFileInfo)},variableCurly:function(){var e,n,r=o;if(s.charAt(o)==="@"&&(n=w(/^@\{([\w-]+)\}/)))return new i.Variable("@"+n[1],r,t.currentFileInfo)},color:function(){var e;if(s.charAt(o)==="#"&&(e=w(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/)))return new i.Color(e[1])},dimension:function(){var e,t=s.charCodeAt(o);if(t>57||t<43||t===47||t==44)return;if(e=w(/^([+-]?\d*\.?\d+)(%|[a-z]+)?/))return new i.Dimension(e[1],e[2])},unicodeDescriptor:function(){var e;if(e=w(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/))return new i.UnicodeDescriptor(e[0])},javascript:function(){var e,t=o,n;s.charAt(t)==="~"&&(t++,n=!0);if(s.charAt(t)!=="`")return;n&&w("~");if(e=w(/^`([^`]*)`/))return new i.JavaScript(e[1],o,n)}},variable:function(){var e;if(s.charAt(o)==="@"&&(e=w(/^(@[\w-]+)\s*:/)))return e[1]},extend:function(e){var t,n,r=o,s,u=[];if(!w(e?/^&:extend\(/:/^:extend\(/))return;do{s=null,t=[];for(;;){s=w(/^(all)(?=\s*(\)|,))/);if(s)break;n=w(this.element);if(!n)break;t.push(n)}s=s&&s[1],u.push(new i.Extend(new i.Selector(t),s,r))}while(w(","));return S(/^\)/),e&&S(/^;/),u},extendRule:function(){return this.extend(!0)},mixin:{call:function(){var e=[],n,r,u,a,f,l=o,c=s.charAt(o),h=!1;if(c!=="."&&c!=="#")return;m();while(n=w(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/))e.push(new i.Element(r,n,o)),r=w(">");w("(")&&(u=this.mixin.args.call(this,!0).args,S(")")),u=u||[],w(this.important)&&(h=!0);if(e.length>0&&(w(";")||T("}")))return new i.mixin.Call(e,u,l,t.currentFileInfo,h);g()},args:function(e){var t=[],n=[],r,u=[],a,f,l,c,h,p={args:null,variadic:!1};for(;;){if(e)h=w(this.expression);else{w(this.comment);if(s.charAt(o)==="."&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({variadic:!0});break}h=w(this.entities.variable)||w(this.entities.literal)||w(this.entities.keyword)}if(!h)break;l=null,h.throwAwayComments&&h.throwAwayComments(),c=h;var d=null;if(e){if(h.value.length==1)var d=h.value[0]}else d=h;if(d&&d instanceof i.Variable)if(w(":"))t.length>0&&(r&&x("Cannot mix ; and , as delimiter types"),a=!0),c=S(this.expression),l=f=d.name;else{if(!e&&w(/^\.{3}/)){p.variadic=!0,w(";")&&!r&&(r=!0),(r?n:u).push({name:h.name,variadic:!0});break}e||(f=l=d.name,c=null)}c&&t.push(c),u.push({name:l,value:c});if(w(","))continue;if(w(";")||r)a&&x("Cannot mix ; and , as delimiter types"),r=!0,t.length>1&&(c=new i.Value(t)),n.push({name:f,value:c}),f=null,t=[],a=!1}return p.args=r?n:u,p},definition:function(){var e,t=[],n,r,u,a,f,c=!1;if(s.charAt(o)!=="."&&s.charAt(o)!=="#"||T(/^[^{]*\}/))return;m();if(n=w(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=n[1];var h=this.mixin.args.call(this,!1);t=h.args,c=h.variadic,w(")")||(l=o,g()),w(this.comment),w(/^when/)&&(f=S(this.conditions,"expected condition")),r=w(this.block);if(r)return new i.mixin.Definition(e,t,r,f,c);g()}}},entity:function(){return w(this.entities.literal)||w(this.entities.variable)||w(this.entities.url)||w(this.entities.call)||w(this.entities.keyword)||w(this.entities.javascript)||w(this.comment)},end:function(){return w(";")||T("}")},alpha:function(){var e;if(!w(/^\(opacity=/i))return;if(e=w(/^\d+/)||w(this.entities.variable))return S(")"),new i.Alpha(e)},element:function(){var e,t,n,r;n=w(this.combinator),e=w(/^(?:\d+\.\d+|\d+)%/)||w(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||w("*")||w("&")||w(this.attribute)||w(/^\([^()@]+\)/)||w(/^[\.#](?=@)/)||w(this.entities.variableCurly),e||w("(")&&(r=w(this.selector))&&w(")")&&(e=new i.Paren(r));if(e)return new i.Element(n,e,o)},combinator:function(){var e=s.charAt(o);if(e===">"||e==="+"||e==="~"||e==="|"){o++;while(s.charAt(o).match(/\s/))o++;return new i.Combinator(e)}return s.charAt(o-1).match(/\s/)?new i.Combinator(" "):new i.Combinator(null)},selector:function(){var e,t,n=[],r,u,a=[];while((u=w(this.extend))||(t=w(this.element))){u?a.push.apply(a,u):(a.length&&x("Extend can only be used at the end of selector"),r=s.charAt(o),n.push(t),t=null);if(r==="{"||r==="}"||r===";"||r===","||r===")")break}if(n.length>0)return new i.Selector(n,a);a.length&&x("Extend must be used to extend a selector, it cannot be used on its own")},attribute:function(){var e="",t,n,r;if(!w("["))return;(t=w(this.entities.variableCurly))||(t=S(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/));if(r=w(/^[|~*$^]?=/))n=w(this.entities.quoted)||w(/^[\w-]+/)||w(this.entities.variableCurly);return S("]"),new i.Attribute(t,r,n)},block:function(){var e;if(w("{")&&(e=w(this.primary))&&w("}"))return e},ruleset:function(){var e=[],n,r,u;m(),t.dumpLineNumbers&&(u=k(o,s,t));while(n=w(this.selector)){e.push(n),w(this.comment);if(!w(","))break;w(this.comment)}if(e.length>0&&(r=w(this.block))){var a=new i.Ruleset(e,r,t.strictImports);return t.dumpLineNumbers&&(a.debugInfo=u),a}l=o,g()},rule:function(e){var n,r,u=s.charAt(o),a;m();if(u==="."||u==="#"||u==="&")return;if(n=w(this.variable)||w(this.property)){r=!e&&(t.compress||n.charAt(0)==="@")?w(this.value)||w(this.anonymousValue):w(this.anonymousValue)||w(this.value),a=w(this.important);if(r&&w(this.end))return new i.Rule(n,r,a,f,t.currentFileInfo);l=o,g();if(r&&!e)return this.rule(!0)}},anonymousValue:function(){var e;if(e=/^([^@+\/'"*`(;{}-]*);/.exec(c[u]))return o+=e[0].length-1,new i.Anonymous(e[1])},"import":function(){var e,n,r=o;m();var s=w(/^@import?\s+/),u=(s?w(this.importOptions):null)||{};if(s&&(e=w(this.entities.quoted)||w(this.entities.url))){n=w(this.mediaFeatures);if(w(";"))return n=n&&new i.Value(n),new i.Import(e,n,u,r,t.currentFileInfo)}g()},importOptions:function(){var e,t={},n,r;if(!w("("))return null;do if(e=w(this.importOption)){n=e,r=!0;switch(n){case"css":n="less",r=!1;break;case"once":n="multiple",r=!1}t[n]=r;if(!w(","))break}while(e);return S(")"),t},importOption:function(){var e=w(/^(less|css|multiple|once)/);if(e)return e[1]},mediaFeature:function(){var e,n,r=[];do if(e=w(this.entities.keyword))r.push(e);else if(w("(")){n=w(this.property),e=w(this.value);if(!w(")"))return null;if(n&&e)r.push(new i.Paren(new i.Rule(n,e,null,o,t.currentFileInfo,!0)));else{if(!e)return null;r.push(new i.Paren(e))}}while(e);if(r.length>0)return new i.Expression(r)},mediaFeatures:function(){var e,t=[];do if(e=w(this.mediaFeature)){t.push(e);if(!w(","))break}else if(e=w(this.entities.variable)){t.push(e);if(!w(","))break}while(e);return t.length>0?t:null},media:function(){var e,n,r,u;t.dumpLineNumbers&&(u=k(o,s,t));if(w(/^@media/)){e=w(this.mediaFeatures);if(n=w(this.block))return r=new i.Media(n,e),t.dumpLineNumbers&&(r.debugInfo=u),r}},directive:function(){var e,n,r,u,a,f,l,c,h,p;if(s.charAt(o)!=="@")return;if(n=w(this["import"])||w(this.media))return n;m(),e=w(/^@[a-z-]+/);if(!e)return;l=e,e.charAt(1)=="-"&&e.indexOf("-",2)>0&&(l="@"+e.slice(e.indexOf("-",2)+1));switch(l){case"@font-face":c=!0;break;case"@viewport":case"@top-left":case"@top-left-corner":case"@top-center":case"@top-right":case"@top-right-corner":case"@bottom-left":case"@bottom-left-corner":case"@bottom-center":case"@bottom-right":case"@bottom-right-corner":case"@left-top":case"@left-middle":case"@left-bottom":case"@right-top":case"@right-middle":case"@right-bottom":c=!0;break;case"@page":case"@document":case"@supports":case"@keyframes":c=!0,h=!0;break;case"@namespace":p=!0}h&&(e+=" "+(w(/^[^{]+/)||"").trim());if(c){if(r=w(this.block))return new i.Directive(e,r)}else if((n=p?w(this.expression):w(this.entity))&&w(";")){var d=new i.Directive(e,n);return t.dumpLineNumbers&&(d.debugInfo=k(o,s,t)),d}g()},value:function(){var e,t=[],n;while(e=w(this.expression)){t.push(e);if(!w(","))break}if(t.length>0)return new i.Value(t)},important:function(){if(s.charAt(o)==="!")return w(/^! *important/)},sub:function(){var e,t;if(w("("))if(e=w(this.addition))return t=new i.Expression([e]),S(")"),t.parens=!0,t},multiplication:function(){var e,t,n,r,u,a=[];if(e=w(this.operand)){u=b(s.charAt(o-1));while(!T(/^\/[*\/]/)&&(n=w("/")||w("*"))){if(!(t=w(this.operand)))break;e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1))}return r||e}},addition:function(){var e,t,n,r,u;if(e=w(this.multiplication)){u=b(s.charAt(o-1));while((n=w(/^[-+]\s+/)||!u&&(w("+")||w("-")))&&(t=w(this.multiplication)))e.parensInOp=!0,t.parensInOp=!0,r=new i.Operation(n,[r||e,t],u),u=b(s.charAt(o-1));return r||e}},conditions:function(){var e,t,n=o,r;if(e=w(this.condition)){while(w(",")&&(t=w(this.condition)))r=new i.Condition("or",r||e,t,n);return r||e}},condition:function(){var e,t,n,r,s=o,u=!1;w(/^not/)&&(u=!0),S("(");if(e=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))return(r=w(/^(?:>=|=<|[<=>])/))?(t=w(this.addition)||w(this.entities.keyword)||w(this.entities.quoted))?n=new i.Condition(r,e,t,s,u):x("expected expression"):n=new i.Condition("=",e,new i.Keyword("true"),s,u),S(")"),w(/^and/)?new i.Condition("and",n,w(this.condition)):n},operand:function(){var e,t=s.charAt(o+1);s.charAt(o)==="-"&&(t==="@"||t==="(")&&(e=w("-"));var n=w(this.sub)||w(this.entities.dimension)||w(this.entities.color)||w(this.entities.variable)||w(this.entities.call);return e&&(n.parensInOp=!0,n=new i.Negative(n)),n},expression:function(){var e,t,n=[],r;while(e=w(this.addition)||w(this.entity))n.push(e),!T(/^\/[\/*]/)&&(t=w("/"))&&n.push(new i.Anonymous(t));if(n.length>0)return new i.Expression(n)},property:function(){var e;if(e=w(/^(\*?-?[_a-z0-9-]+)\s*:/))return e[1]}}}};if(r.mode==="browser"||r.mode==="rhino")r.Parser.importer=function(e,t,n,r){!/^([a-z-]+:)?\//.test(e)&&t.currentDirectory&&(e=t.currentDirectory+e);var i=r.toSheet(e);i.processImports=!1,i.currentFileInfo=t,w(i,function(e,t,r,i,s,o){n.call(null,e,t,o)},!0)};(function(r){function u(e){return r.functions.hsla(e.h,e.s,e.l,e.a)}function a(e,t){return e instanceof r.Dimension&&e.unit.is("%")?parseFloat(e.value*t/100):f(e)}function f(e){if(e instanceof r.Dimension)return parseFloat(e.unit.is("%")?e.value/100:e.value);if(typeof e=="number")return e;throw{error:"RuntimeError",message:"color functions take numbers as parameters"}}function l(e){return Math.min(1,Math.max(0,e))}r.functions={rgb:function(e,t,n){return this.rgba(e,t,n,1)},rgba:function(e,t,n,i){var s=[e,t,n].map(function(e){return a(e,256)});return i=f(i),new r.Color(s,i)},hsl:function(e,t,n){return this.hsla(e,t,n,1)},hsla:function(e,t,n,r){function o(e){return e=e<0?e+1:e>1?e-1:e,e*6<1?s+(i-s)*e*6:e*2<1?i:e*3<2?s+(i-s)*(2/3-e)*6:s}e=f(e)%360/360,t=l(f(t)),n=l(f(n)),r=l(f(r));var i=n<=.5?n*(t+1):n+t-n*t,s=n*2-i;return this.rgba(o(e+1/3)*255,o(e)*255,o(e-1/3)*255,r)},hsv:function(e,t,n){return this.hsva(e,t,n,1)},hsva:function(e,t,n,r){e=f(e)%360/360*360,t=f(t),n=f(n),r=f(r);var i,s;i=Math.floor(e/60%6),s=e/60-i;var o=[n,n*(1-t),n*(1-s*t),n*(1-(1-s)*t)],u=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return this.rgba(o[u[i][0]]*255,o[u[i][1]]*255,o[u[i][2]]*255,r)},hue:function(e){return new r.Dimension(Math.round(e.toHSL().h))},saturation:function(e){return new r.Dimension(Math.round(e.toHSL().s*100),"%")},lightness:function(e){return new r.Dimension(Math.round(e.toHSL().l*100),"%")},hsvhue:function(e){return new r.Dimension(Math.round(e.toHSV().h))},hsvsaturation:function(e){return new r.Dimension(Math.round(e.toHSV().s*100),"%")},hsvvalue:function(e){return new r.Dimension(Math.round(e.toHSV().v*100),"%")},red:function(e){return new r.Dimension(e.rgb[0])},green:function(e){return new r.Dimension(e.rgb[1])},blue:function(e){return new r.Dimension(e.rgb[2])},alpha:function(e){return new r.Dimension(e.toHSL().a)},luma:function(e){return new r.Dimension(Math.round(e.luma()*e.alpha*100),"%")},saturate:function(e,t){var n=e.toHSL();return n.s+=t.value/100,n.s=l(n.s),u(n)},desaturate:function(e,t){var n=e.toHSL();return n.s-=t.value/100,n.s=l(n.s),u(n)},lighten:function(e,t){var n=e.toHSL();return n.l+=t.value/100,n.l=l(n.l),u(n)},darken:function(e,t){var n=e.toHSL();return n.l-=t.value/100,n.l=l(n.l),u(n)},fadein:function(e,t){var n=e.toHSL();return n.a+=t.value/100,n.a=l(n.a),u(n)},fadeout:function(e,t){var n=e.toHSL();return n.a-=t.value/100,n.a=l(n.a),u(n)},fade:function(e,t){var n=e.toHSL();return n.a=t.value/100,n.a=l(n.a),u(n)},spin:function(e,t){var n=e.toHSL(),r=(n.h+t.value)%360;return n.h=r<0?360+r:r,u(n)},mix:function(e,t,n){n||(n=new r.Dimension(50));var i=n.value/100,s=i*2-1,o=e.toHSL().a-t.toHSL().a,u=((s*o==-1?s:(s+o)/(1+s*o))+1)/2,a=1-u,f=[e.rgb[0]*u+t.rgb[0]*a,e.rgb[1]*u+t.rgb[1]*a,e.rgb[2]*u+t.rgb[2]*a],l=e.alpha*i+t.alpha*(1-i);return new r.Color(f,l)},greyscale:function(e){return this.desaturate(e,new r.Dimension(100))},contrast:function(e,t,n,r){if(!e.rgb)return null;typeof n=="undefined"&&(n=this.rgba(255,255,255,1)),typeof t=="undefined"&&(t=this.rgba(0,0,0,1));if(t.luma()>n.luma()){var i=n;n=t,t=i}return typeof r=="undefined"?r=.43:r=f(r),e.luma()*e.alpha<r?n:t},e:function(e){return new r.Anonymous(e instanceof r.JavaScript?e.evaluated:e)},escape:function(e){return new r.Anonymous(encodeURI(e.value).replace(/=/g,"%3D").replace(/:/g,"%3A").replace(/#/g,"%23").replace(/;/g,"%3B").replace(/\(/g,"%28").replace(/\)/g,"%29"))},"%":function(e){var t=Array.prototype.slice.call(arguments,1),n=e.value;for(var i=0;i<t.length;i++)n=n.replace(/%[sda]/i,function(e){var n=e.match(/s/i)?t[i].value:t[i].toCSS();return e.match(/[A-Z]$/)?encodeURIComponent(n):n});return n=n.replace(/%%/g,"%"),new r.Quoted('"'+n+'"',n)},unit:function(e,t){return new r.Dimension(e.value,t?t.toCSS():"")},convert:function(e,t){return e.convertTo(t.value)},round:function(e,t){var n=typeof t=="undefined"?0:t.value;return this._math(function(e){return e.toFixed(n)},null,e)},pi:function(){return new r.Dimension(Math.PI)},mod:function(e,t){return new r.Dimension(e.value%t.value,e.unit)},pow:function(e,t){if(typeof e=="number"&&typeof t=="number")e=new r.Dimension(e),t=new r.Dimension(t);else if(!(e instanceof r.Dimension)||!(t instanceof r.Dimension))throw{type:"Argument",message:"arguments must be numbers"};return new r.Dimension(Math.pow(e.value,t.value),e.unit)},_math:function(e,t,n){if(n instanceof r.Dimension)return new r.Dimension(e(parseFloat(n.value)),t==null?n.unit:t);if(typeof n=="number")return e(n);throw{type:"Argument",message:"argument must be a number"}},argb:function(e){return new r.Anonymous(e.toARGB())},percentage:function(e){return new r.Dimension(e.value*100,"%")},color:function(e){if(e instanceof r.Quoted)return new r.Color(e.value.slice(1));throw{type:"Argument",message:"argument must be a string"}},iscolor:function(e){return this._isa(e,r.Color)},isnumber:function(e){return this._isa(e,r.Dimension)},isstring:function(e){return this._isa(e,r.Quoted)},iskeyword:function(e){return this._isa(e,r.Keyword)},isurl:function(e){return this._isa(e,r.URL)},ispixel:function(e){return this.isunit(e,"px")},ispercentage:function(e){return this.isunit(e,"%")},isem:function(e){return this.isunit(e,"em")},isunit:function(e,t){return e instanceof r.Dimension&&e.unit.is(t.value||t)?r.True:r.False},_isa:function(e,t){return e instanceof t?r.True:r.False},multiply:function(e,t){var n=e.rgb[0]*t.rgb[0]/255,r=e.rgb[1]*t.rgb[1]/255,i=e.rgb[2]*t.rgb[2]/255;return this.rgb(n,r,i)},screen:function(e,t){var n=255-(255-e.rgb[0])*(255-t.rgb[0])/255,r=255-(255-e.rgb[1])*(255-t.rgb[1])/255,i=255-(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},overlay:function(e,t){var n=e.rgb[0]<128?2*e.rgb[0]*t.rgb[0]/255:255-2*(255-e.rgb[0])*(255-t.rgb[0])/255,r=e.rgb[1]<128?2*e.rgb[1]*t.rgb[1]/255:255-2*(255-e.rgb[1])*(255-t.rgb[1])/255,i=e.rgb[2]<128?2*e.rgb[2]*t.rgb[2]/255:255-2*(255-e.rgb[2])*(255-t.rgb[2])/255;return this.rgb(n,r,i)},softlight:function(e,t){var n=t.rgb[0]*e.rgb[0]/255,r=n+e.rgb[0]*(255-(255-e.rgb[0])*(255-t.rgb[0])/255-n)/255;n=t.rgb[1]*e.rgb[1]/255;var i=n+e.rgb[1]*(255-(255-e.rgb[1])*(255-t.rgb[1])/255-n)/255;n=t.rgb[2]*e.rgb[2]/255;var s=n+e.rgb[2]*(255-(255-e.rgb[2])*(255-t.rgb[2])/255-n)/255;return this.rgb(r,i,s)},hardlight:function(e,t){var n=t.rgb[0]<128?2*t.rgb[0]*e.rgb[0]/255:255-2*(255-t.rgb[0])*(255-e.rgb[0])/255,r=t.rgb[1]<128?2*t.rgb[1]*e.rgb[1]/255:255-2*(255-t.rgb[1])*(255-e.rgb[1])/255,i=t.rgb[2]<128?2*t.rgb[2]*e.rgb[2]/255:255-2*(255-t.rgb[2])*(255-e.rgb[2])/255;return this.rgb(n,r,i)},difference:function(e,t){var n=Math.abs(e.rgb[0]-t.rgb[0]),r=Math.abs(e.rgb[1]-t.rgb[1]),i=Math.abs(e.rgb[2]-t.rgb[2]);return this.rgb(n,r,i)},exclusion:function(e,t){var n=e.rgb[0]+t.rgb[0]*(255-e.rgb[0]-e.rgb[0])/255,r=e.rgb[1]+t.rgb[1]*(255-e.rgb[1]-e.rgb[1])/255,i=e.rgb[2]+t.rgb[2]*(255-e.rgb[2]-e.rgb[2])/255;return this.rgb(n,r,i)},average:function(e,t){var n=(e.rgb[0]+t.rgb[0])/2,r=(e.rgb[1]+t.rgb[1])/2,i=(e.rgb[2]+t.rgb[2])/2;return this.rgb(n,r,i)},negation:function(e,t){var n=255-Math.abs(255-t.rgb[0]-e.rgb[0]),r=255-Math.abs(255-t.rgb[1]-e.rgb[1]),i=255-Math.abs(255-t.rgb[2]-e.rgb[2]);return this.rgb(n,r,i)},tint:function(e,t){return this.mix(this.rgb(255,255,255),e,t)},shade:function(e,t){return this.mix(this.rgb(0,0,0),e,t)},extract:function(e,t){return t=t.value-1,e.value[t]},"data-uri":function(t,i){if(typeof e!="undefined")return(new r.URL(i||t,this.currentFileInfo)).eval(this.env);var s=t.value,o=i&&i.value,u=n("fs"),a=n("path"),f=!1;arguments.length<2&&(o=s),this.env.isPathRelative(o)&&(this.currentFileInfo.relativeUrls?o=a.join(this.currentFileInfo.currentDirectory,o):o=a.join(this.currentFileInfo.entryPath,o));if(arguments.length<2){var l;try{l=n("mime")}catch(c){l=r._mime}s=l.lookup(o);var h=l.charsets.lookup(s);f=["US-ASCII","UTF-8"].indexOf(h)<0,f&&(s+=";base64")}else f=/;base64$/.test(s);var p=u.readFileSync(o),d=32,v=parseInt(p.length/1024,10);if(v>=d){if(this.env.ieCompat!==!1)return this.env.silent||console.warn("Skipped data-uri embedding of %s because its size (%dKB) exceeds IE8-safe %dKB!",o,v,d),(new r.URL(i||t,this.currentFileInfo)).eval(this.env);this.env.silent||console.warn("WARNING: Embedding %s (%dKB) exceeds IE8's data-uri size limit of %dKB!",o,v,d)}p=f?p.toString("base64"):encodeURIComponent(p);var m="'data:"+s+","+p+"'";return new r.URL(new r.Anonymous(m))}},r._mime={_types:{".htm":"text/html",".html":"text/html",".gif":"image/gif",".jpg":"image/jpeg",".jpeg":"image/jpeg",".png":"image/png"},lookup:function(e){var i=n("path").extname(e),s=r._mime._types[i];if(s===t)throw new Error('Optional dependency "mime" is required for '+i);return s},charsets:{lookup:function(e){return e&&/^text\//.test(e)?"UTF-8":""}}};var i=[{name:"ceil"},{name:"floor"},{name:"sqrt"},{name:"abs"},{name:"tan",unit:""},{name:"sin",unit:""},{name:"cos",unit:""},{name:"atan",unit:"rad"},{name:"asin",unit:"rad"},{name:"acos",unit:"rad"}],s=function(e,t){return function(n){return t!=null&&(n=n.unify()),this._math(Math[e],t,n)}};for(var o=0;o<i.length;o++)r.functions[i[o].name]=s(i[o].name,i[o].unit);r.functionCall=function(e,t){this.env=e,this.currentFileInfo=t},r.functionCall.prototype=r.functions})(n("./tree")),function(e){e.colors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgrey:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta 330.13 +:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",grey:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgrey:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}}(n("./tree")),function(e){e.Alpha=function(e){this.value=e},e.Alpha.prototype={type:"Alpha",accept:function(e){this.value=e.visit(this.value)},eval:function(e){return this.value.eval&&(this.value=this.value.eval(e)),this},toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"}}}(n("../tree")),function(e){e.Anonymous=function(e){this.value=e.value||e},e.Anonymous.prototype={type:"Anonymous",toCSS:function(){return this.value},eval:function(){return this},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Assignment=function(e,t){this.key=e,this.value=t},e.Assignment.prototype={type:"Assignment",accept:function(e){this.value=e.visit(this.value)},toCSS:function(){return this.key+"="+(this.value.toCSS?this.value.toCSS():this.value)},eval:function(t){return this.value.eval?new e.Assignment(this.key,this.value.eval(t)):this}}}(n("../tree")),function(e){e.Call=function(e,t,n,r){this.name=e,this.args=t,this.index=n,this.currentFileInfo=r},e.Call.prototype={type:"Call",accept:function(e){this.args=e.visit(this.args)},eval:function(t){var n=this.args.map(function(e){return e.eval(t)}),r=this.name.toLowerCase(),i,s;if(r in e.functions)try{s=new e.functionCall(t,this.currentFileInfo),i=s[r].apply(s,n);if(i!=null)return i}catch(o){throw{type:o.type||"Runtime",message:"error evaluating function `"+this.name+"`"+(o.message?": "+o.message:""),index:this.index,filename:this.currentFileInfo.filename}}return new e.Anonymous(this.name+"("+n.map(function(e){return e.toCSS(t)}).join(", ")+")")},toCSS:function(e){return this.eval(e).toCSS()}}}(n("../tree")),function(e){e.Color=function(e,t){Array.isArray(e)?this.rgb=e:e.length==6?this.rgb=e.match(/.{2}/g).map(function(e){return parseInt(e,16)}):this.rgb=e.split("").map(function(e){return parseInt(e+e,16)}),this.alpha=typeof t=="number"?t:1},e.Color.prototype={type:"Color",eval:function(){return this},luma:function(){return.2126*this.rgb[0]/255+.7152*this.rgb[1]/255+.0722*this.rgb[2]/255},toCSS:function(e,t){var n=e&&e.compress&&!t;if(this.alpha<1)return"rgba("+this.rgb.map(function(e){return Math.round(e)}).concat(this.alpha).join(","+(n?"":" "))+")";var r=this.rgb.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("");return n&&(r=r.split(""),r[0]==r[1]&&r[2]==r[3]&&r[4]==r[5]?r=r[0]+r[2]+r[4]:r=r.join("")),"#"+r},operate:function(t,n,r){var i=[];r instanceof e.Color||(r=r.toColor());for(var s=0;s<3;s++)i[s]=e.operate(t,n,this.rgb[s],r.rgb[s]);return new e.Color(i,this.alpha+r.alpha)},toHSL:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,l:a,a:r}},toHSV:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255,r=this.alpha,i=Math.max(e,t,n),s=Math.min(e,t,n),o,u,a=i,f=i-s;i===0?u=0:u=f/i;if(i===s)o=0;else{switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,v:a,a:r}},toARGB:function(){var e=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+e.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha===this.alpha?0:-1:-1}}}(n("../tree")),function(e){e.Comment=function(e,t){this.value=e,this.silent=!!t},e.Comment.prototype={type:"Comment",toCSS:function(e){return e.compress?"":this.value},eval:function(){return this}}}(n("../tree")),function(e){e.Condition=function(e,t,n,r,i){this.op=e.trim(),this.lvalue=t,this.rvalue=n,this.index=r,this.negate=i},e.Condition.prototype={type:"Condition",accept:function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)},eval:function(e){var t=this.lvalue.eval(e),n=this.rvalue.eval(e),r=this.index,i,i=function(e){switch(e){case"and":return t&&n;case"or":return t||n;default:if(t.compare)i=t.compare(n);else{if(!n.compare)throw{type:"Type",message:"Unable to perform comparison",index:r};i=n.compare(t)}switch(i){case-1:return e==="<"||e==="=<";case 0:return e==="="||e===">="||e==="=<";case 1:return e===">"||e===">="}}}(this.op);return this.negate?!i:i}}}(n("../tree")),function(e){e.Dimension=function(n,r){this.value=parseFloat(n),this.unit=r&&r instanceof e.Unit?r:new e.Unit(r?[r]:t)},e.Dimension.prototype={type:"Dimension",accept:function(e){this.unit=e.visit(this.unit)},eval:function(e){return this},toColor:function(){return new e.Color([this.value,this.value,this.value])},toCSS:function(e){if(e&&e.strictUnits&&!this.unit.isSingular())throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: "+this.unit.toString());var t=this.value,n=String(t);t!==0&&t<1e-6&&t>-0.000001&&(n=t.toFixed(20).replace(/0+$/,""));if(e&&e.compress){if(t===0&&!this.unit.isAngle())return n;t>0&&t<1&&(n=n.substr(1))}return n+this.unit.toCSS(e)},operate:function(t,n,r){var i=e.operate(t,n,this.value,r.value),s=this.unit.clone();if(n==="+"||n==="-"){if(s.numerator.length===0&&s.denominator.length===0)s.numerator=r.unit.numerator.slice(0),s.denominator=r.unit.denominator.slice(0);else if(r.unit.numerator.length!=0||s.denominator.length!=0){r=r.convertTo(this.unit.usedUnits());if(t.strictUnits&&r.unit.toString()!==s.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+s.toString()+"' and '"+r.unit.toString()+"'.");i=e.operate(t,n,this.value,r.value)}}else n==="*"?(s.numerator=s.numerator.concat(r.unit.numerator).sort(),s.denominator=s.denominator.concat(r.unit.denominator).sort(),s.cancel()):n==="/"&&(s.numerator=s.numerator.concat(r.unit.denominator).sort(),s.denominator=s.denominator.concat(r.unit.numerator).sort(),s.cancel());return new e.Dimension(i,s)},compare:function(t){if(t instanceof e.Dimension){var n=this.unify(),r=t.unify(),i=n.value,s=r.value;return s>i?-1:s<i?1:!r.unit.isEmpty()&&n.unit.compare(r.unit)!==0?-1:0}return-1},unify:function(){return this.convertTo({length:"m",duration:"s",angle:"rad"})},convertTo:function(t){var n=this.value,r=this.unit.clone(),i,s,o,u,a,f={};if(typeof t=="string"){for(i in e.UnitConversions)e.UnitConversions[i].hasOwnProperty(t)&&(f={},f[i]=t);t=f}for(s in t)t.hasOwnProperty(s)&&(a=t[s],o=e.UnitConversions[s],r.map(function(e,t){return o.hasOwnProperty(e)?(t?n/=o[e]/o[a]:n*=o[e]/o[a],a):e}));return r.cancel(),new e.Dimension(n,r)}},e.UnitConversions={length:{m:1,cm:.01,mm:.001,"in":.0254,pt:.0254/72,pc:.0254/72*12},duration:{s:1,ms:.001},angle:{rad:1/(2*Math.PI),deg:1/360,grad:.0025,turn:1}},e.Unit=function(e,t,n){this.numerator=e?e.slice(0).sort():[],this.denominator=t?t.slice(0).sort():[],this.backupUnit=n},e.Unit.prototype={type:"Unit",clone:function(){return new e.Unit(this.numerator.slice(0),this.denominator.slice(0),this.backupUnit)},toCSS:function(e){return this.numerator.length>=1?this.numerator[0]:this.denominator.length>=1?this.denominator[0]:(!e||!e.strictUnits)&&this.backupUnit?this.backupUnit:""},toString:function(){var e,t=this.numerator.join("*");for(e=0;e<this.denominator.length;e++)t+="/"+this.denominator[e];return t},compare:function(e){return this.is(e.toString())?0:-1},is:function(e){return this.toString()===e},isAngle:function(){return e.UnitConversions.angle.hasOwnProperty(this.toCSS())},isEmpty:function(){return this.numerator.length==0&&this.denominator.length==0},isSingular:function(){return this.numerator.length<=1&&this.denominator.length==0},map:function(e){var t;for(t=0;t<this.numerator.length;t++)this.numerator[t]=e(this.numerator[t],!1);for(t=0;t<this.denominator.length;t++)this.denominator[t]=e(this.denominator[t],!0)},usedUnits:function(){var t,n,r={};for(n in e.UnitConversions)e.UnitConversions.hasOwnProperty(n)&&(t=e.UnitConversions[n],this.map(function(e){return t.hasOwnProperty(e)&&!r[n]&&(r[n]=e),e}));return r},cancel:function(){var e={},t,n,r;for(n=0;n<this.numerator.length;n++)t=this.numerator[n],r||(r=t),e[t]=(e[t]||0)+1;for(n=0;n<this.denominator.length;n++)t=this.denominator[n],r||(r=t),e[t]=(e[t]||0)-1;this.numerator=[],this.denominator=[];for(t in e)if(e.hasOwnProperty(t)){var i=e[t];if(i>0)for(n=0;n<i;n++)this.numerator.push(t);else if(i<0)for(n=0;n<-i;n++)this.denominator.push(t)}this.numerator.length===0&&this.denominator.length===0&&r&&(this.backupUnit=r),this.numerator.sort(),this.denominator.sort()}}}(n("../tree")),function(e){e.Directive=function(t,n){this.name=t,Array.isArray(n)?(this.ruleset=new e.Ruleset([],n),this.ruleset.allowImports=!0):this.value=n},e.Directive.prototype={type:"Directive",accept:function(e){this.ruleset=e.visit(this.ruleset),this.value=e.visit(this.value)},toCSS:function(e){return this.ruleset?(this.ruleset.root=!0,this.name+(e.compress?"{":" {\n ")+this.ruleset.toCSS(e).trim().replace(/\n/g,"\n ")+(e.compress?"}":"\n}\n")):this.name+" "+this.value.toCSS()+";\n"},eval:function(t){var n=this;return this.ruleset&&(t.frames.unshift(this),n=new e.Directive(this.name),n.ruleset=this.ruleset.eval(t),t.frames.shift()),n},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)}}}(n("../tree")),function(e){e.Element=function(t,n,r){this.combinator=t instanceof e.Combinator?t:new e.Combinator(t),typeof n=="string"?this.value=n.trim():n?this.value=n:this.value="",this.index=r},e.Element.prototype={type:"Element",accept:function(e){this.combinator=e.visit(this.combinator),this.value=e.visit(this.value)},eval:function(t){return new e.Element(this.combinator,this.value.eval?this.value.eval(t):this.value,this.index)},toCSS:function(e){var t=this.value.toCSS?this.value.toCSS(e):this.value;return t==""&&this.combinator.value.charAt(0)=="&"?"":this.combinator.toCSS(e||{})+t}},e.Attribute=function(e,t,n){this.key=e,this.op=t,this.value=n},e.Attribute.prototype={type:"Attribute",accept:function(e){this.value=e.visit(this.value)},eval:function(t){return new e.Attribute(this.key.eval?this.key.eval(t):this.key,this.op,this.value&&this.value.eval?this.value.eval(t):this.value)},toCSS:function(e){var t=this.key.toCSS?this.key.toCSS(e):this.key;return this.op&&(t+=this.op,t+=this.value.toCSS?this.value.toCSS(e):this.value),"["+t+"]"}},e.Combinator=function(e){e===" "?this.value=" ":this.value=e?e.trim():""},e.Combinator.prototype={type:"Combinator",toCSS:function(e){return{"":""," ":" ",":":" :","+":e.compress?"+":" + ","~":e.compress?"~":" ~ ",">":e.compress?">":" > ","|":e.compress?"|":" | "}[this.value]}}}(n("../tree")),function(e){e.Expression=function(e){this.value=e},e.Expression.prototype={type:"Expression",accept:function(e){this.value=e.visit(this.value)},eval:function(t){var n,r=this.parens&&!this.parensInOp,i=!1;return r&&t.inParenthesis(),this.value.length>1?n=new e.Expression(this.value.map(function(e){return e.eval(t)})):this.value.length===1?(this.value[0].parens&&!this.value[0].parensInOp&&(i=!0),n=this.value[0].eval(t)):n=this,r&&t.outOfParenthesis(),this.parens&&this.parensInOp&&!t.isMathOn()&&!i&&(n=new e.Paren(n)),n},toCSS:function(e){return this.value.map(function(t){return t.toCSS?t.toCSS(e):""}).join(" ")},throwAwayComments:function(){this.value=this.value.filter(function(t){return!(t instanceof e.Comment)})}}}(n("../tree")),function(e){e.Extend=function(t,n,r){this.selector=t,this.option=n,this.index=r;switch(n){case"all":this.allowBefore=!0,this.allowAfter=!0;break;default:this.allowBefore=!1,this.allowAfter=!1}},e.Extend.prototype={type:"Extend",accept:function(e){this.selector=e.visit(this.selector)},eval:function(t){return new e.Extend(this.selector.eval(t),this.option,this.index)},clone:function(t){return new e.Extend(this.selector,this.option,this.index)},findSelfSelectors:function(e){var t=[],n;for(n=0;n<e.length;n++)t=t.concat(e[n].elements);this.selfSelectors=[{elements:t}]}}}(n("../tree")),function(e){e.Import=function(e,n,r,i,s){var o=this;this.options=r,this.index=i,this.path=e,this.features=n,this.currentFileInfo=s;if(this.options.less!==t)this.css=!this.options.less;else{var u=this.getPath();u&&/css([\?;].*)?$/.test(u)&&(this.css=!0)}},e.Import.prototype={type:"Import",accept:function(e){this.features=e.visit(this.features),this.path=e.visit(this.path),this.root=e.visit(this.root)},toCSS:function(e){var t=this.features?" "+this.features.toCSS(e):"";return this.css?"@import "+this.path.toCSS()+t+";\n":""},getPath:function(){if(this.path instanceof e.Quoted){var n=this.path.value;return this.css!==t||/(\.[a-z]*$)|([\?;].*)$/.test(n)?n:n+".less"}return this.path instanceof e.URL?this.path.value.value:null},evalForImport:function(t){return new e.Import(this.path.eval(t),this.features,this.options,this.index,this.currentFileInfo)},evalPath:function(t){var n=this.path.eval(t),r=this.currentFileInfo&&this.currentFileInfo.rootpath;if(r&&!(n instanceof e.URL)){var i=n.value;i&&t.isPathRelative(i)&&(n.value=r+i)}return n},eval:function(t){var n,r=this.features&&this.features.eval(t);if(this.skip)return[];if(this.css){var i=new e.Import(this.evalPath(t),r,this.options,this.index);if(!i.css&&this.error)throw this.error;return i}return n=new e.Ruleset([],this.root.rules.slice(0)),n.evalImports(t),this.features?new e.Media(n.rules,this.features.value):n.rules}}}(n("../tree")),function(e){e.JavaScript=function(e,t,n){this.escaped=n,this.expression=e,this.index=t},e.JavaScript.prototype={type:"JavaScript",eval:function(t){var n,r=this,i={},s=this.expression.replace(/@\{([\w-]+)\}/g,function(n,i){return e.jsify((new e.Variable("@"+i,r.index)).eval(t))});try{s=new Function("return ("+s+")")}catch(o){throw{message:"JavaScript evaluation error: `"+s+"`",index:this.index}}for(var u in t.frames[0].variables())i[u.slice(1)]={value:t.frames[0].variables()[u].value,toJS:function(){return this.value.eval(t).toCSS()}};try{n=s.call(i)}catch(o){throw{message:"JavaScript evaluation error: '"+o.name+": "+o.message+"'",index:this.index}}return typeof n=="string"?new e.Quoted('"'+n+'"',n,this.escaped,this.index):Array.isArray(n)?new e.Anonymous(n.join(", ")):new e.Anonymous(n)}}}(n("../tree")),function(e){e.Keyword=function(e){this.value=e},e.Keyword.prototype={type:"Keyword",eval:function(){return this},toCSS:function(){return this.value},compare:function(t){return t instanceof e.Keyword?t.value===this.value?0:1:-1}},e.True=new e.Keyword("true"),e.False=new e.Keyword("false")}(n("../tree")),function(e){e.Media=function(t,n){var r=this.emptySelectors();this.features=new e.Value(n),this.ruleset=new e.Ruleset(r,t),this.ruleset.allowImports=!0},e.Media.prototype={type:"Media",accept:function(e){this.features=e.visit(this.features),this.ruleset=e.visit(this.ruleset)},toCSS:function(e){var t=this.features.toCSS(e);return"@media "+t+(e.compress?"{":" {\n ")+this.ruleset.toCSS(e).trim().replace(/\n/g,"\n ")+(e.compress?"}":"\n}\n")},eval:function(t){t.mediaBlocks||(t.mediaBlocks=[],t.mediaPath=[]);var n=new e.Media([],[]);this.debugInfo&&(this.ruleset.debugInfo=this.debugInfo,n.debugInfo=this.debugInfo);var r=!1;t.strictMath||(r=!0,t.strictMath=!0);try{n.features=this.features.eval(t)}finally{r&&(t.strictMath=!1)}return t.mediaPath.push(n),t.mediaBlocks.push(n),t.frames.unshift(this.ruleset),n.ruleset=this.ruleset.eval(t),t.frames.shift(),t.mediaPath.pop(),t.mediaPath.length===0?n.evalTop(t):n.evalNested(t)},variable:function(t){return e.Ruleset.prototype.variable.call(this.ruleset,t)},find:function(){return e.Ruleset.prototype.find.apply(this.ruleset,arguments)},rulesets:function(){return e.Ruleset.prototype.rulesets.apply(this.ruleset)},emptySelectors:function(){var t=new e.Element("","&",0);return[new e.Selector([t])]},evalTop:function(t){var n=this;if(t.mediaBlocks.length>1){var r=this.emptySelectors();n=new e.Ruleset(r,t.mediaBlocks),n.multiMedia=!0}return delete t.mediaBlocks,delete t.mediaPath,n},evalNested:function(t){var n,r,i=t.mediaPath.concat([this]);for(n=0;n<i.length;n++)r=i[n].features instanceof e.Value?i[n].features.value:i[n].features,i[n]=Array.isArray(r)?r:[r];return this.features=new e.Value(this.permute(i).map(function(t){t=t.map(function(t){return t.toCSS?t:new e.Anonymous(t)});for(n=t.length-1;n>0;n--)t.splice(n,0,new e.Anonymous("and"));return new e.Expression(t)})),new e.Ruleset([],[])},permute:function(e){if(e.length===0)return[];if(e.length===1)return e[0];var t=[],n=this.permute(e.slice(1));for(var r=0;r<n.length;r++)for(var i=0;i<e[0].length;i++)t.push([e[0][i]].concat(n[r]));return t},bubbleSelectors:function(t){this.ruleset=new e.Ruleset(t.slice(0),[this.ruleset])}}}(n("../tree")),function(e){e.mixin={},e.mixin.Call=function(t,n,r,i,s){this.selector=new e.Selector(t),this.arguments=n,this.index=r,this.currentFileInfo=i,this.important=s},e.mixin.Call.prototype={type:"MixinCall",accept:function(e){this.selector=e.visit(this.selector),this.arguments=e.visit(this.arguments)},eval:function(t){var n,r,i,s=[],o=!1,u,a,f,l,c;i=this.arguments&&this.arguments.map(function(e){return{name:e.name,value:e.value.eval(t)}});for(u=0;u<t.frames.length;u++)if((n=t.frames[u].find(this.selector)).length>0){c=!0;for(a=0;a<n.length;a++){r=n[a],l=!1;for(f=0;f<t.frames.length;f++)if(!(r instanceof e.mixin.Definition)&&r===(t.frames[f].originalRuleset||t.frames[f])){l=!0;break}if(l)continue;if(r.matchArgs(i,t)){if(!r.matchCondition||r.matchCondition(i,t))try{Array.prototype.push.apply(s,r.eval(t,i,this.important).rules)}catch(h){throw{message:h.message,index:this.index,filename:this.currentFileInfo.filename,stack:h.stack}}o=!0}}if(o)return s}throw c?{type:"Runtime",message:"No matching definition was found for `"+this.selector.toCSS().trim()+"("+(i?i.map(function(e){var t="";return e.name&&(t+=e.name+":"),e.value.toCSS?t+=e.value.toCSS():t+="???",t}).join(", "):"")+")`",index:this.index,filename:this.currentFileInfo.filename}:{type:"Name",message:this.selector.toCSS().trim()+" is undefined",index:this.index,filename:this.currentFileInfo.filename}}},e.mixin.Definition=function(t,n,r,i,s){this.name=t,this.selectors=[new e.Selector([new e.Element(null,t)])],this.params=n,this.condition=i,this.variadic=s,this.arity=n.length,this.rules=r,this._lookups={},this.required=n.reduce(function(e,t){return!t.name||t.name&&!t.value?e+1:e},0),this.parent=e.Ruleset.prototype,this.frames=[]},e.mixin.Definition.prototype={type:"MixinDefinition",accept:function(e){this.params=e.visit(this.params),this.rules=e.visit(this.rules),this.condition=e.visit(this.condition)},toCSS:function(){return""},variable:function(e){return this.parent.variable.call(this,e)},variables:function(){return this.parent.variables.call(this)},find:function(){return this.parent.find.apply(this,arguments)},rulesets:function(){return this.parent.rulesets.apply(this)},evalParams:function(t,n,r,i){var s=new e.Ruleset(null,[]),o,u,a=this.params.slice(0),f,l,c,h,p,d;n=new e.evalEnv(n,[s].concat(n.frames));if(r){r=r.slice(0);for(f=0;f<r.length;f++){u=r[f];if(h=u&&u.name){p=!1;for(l=0;l<a.length;l++)if(!i[l]&&h===a[l].name){i[l]=u.value.eval(t),s.rules.unshift(new e.Rule(h,u.value.eval(t))),p=!0;break}if(p){r.splice(f,1),f--;continue}throw{type:"Runtime",message:"Named argument for "+this.name+" "+r[f].name+" not found"}}}}d=0;for(f=0;f<a.length;f++){if(i[f])continue;u=r&&r[d];if(h=a[f].name)if(a[f].variadic&&r){o=[];for(l=d;l<r.length;l++)o.push(r[l].value.eval(t));s.rules.unshift(new e.Rule(h,(new e.Expression(o)).eval(t)))}else{c=u&&u.value;if(c)c=c.eval(t);else{if(!a[f].value)throw{type:"Runtime",message:"wrong number of arguments for "+this.name+" ("+r.length+" for "+this.arity+")"};c=a[f].value.eval(n),s.resetCache()}s.rules.unshift(new e.Rule(h,c)),i[f]=c}if(a[f].variadic&&r)for(l=d;l<r.length;l++)i[l]=r[l].value.eval(t);d++}return s},eval:function(t,n,r){var i=[],s=this.frames.concat(t.frames),o=this.evalParams(t,new e.evalEnv(t,s),n,i),u,a,f,l;return o.rules.unshift(new e.Rule("@arguments",(new e.Expression(i)).eval(t))),a=r?this.parent.makeImportant.apply(this).rules:this.rules.slice(0),l=(new e.Ruleset(null,a)).eval(new e.evalEnv(t,[this,o].concat(s))),l.originalRuleset=this,l},matchCondition:function(t,n){return this.condition&&!this.condition.eval(new e.evalEnv(n,[this.evalParams(n,new e.evalEnv(n,this.frames.concat(n.frames)),t,[])].concat(n.frames)))?!1:!0},matchArgs:function(e,t){var n=e&&e.length||0,r,i;if(!this.variadic){if(n<this.required)return!1;if(n>this.params.length)return!1;if(this.required>0&&n>this.params.length)return!1}r=Math.min(n,this.arity);for(var s=0;s<r;s++)if(!this.params[s].name&&!this.params[s].variadic&&e[s].value.eval(t).toCSS()!=this.params[s].value.eval(t).toCSS())return!1;return!0}}}(n("../tree")),function(e){e.Negative=function(e){this.value=e},e.Negative.prototype={type:"Negative",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){return"-"+this.value.toCSS(e)},eval:function(t){return t.isMathOn()?(new e.Operation("*",[new e.Dimension(-1),this.value])).eval(t):new e.Negative(this.value.eval(t))}}}(n("../tree")),function(e){e.Operation=function(e,t,n){this.op=e.trim(),this.operands=t,this.isSpaced=n},e.Operation.prototype={type:"Operation",accept:function(e){this.operands=e.visit(this.operands)},eval:function(t){var n=this.operands[0].eval(t),r=this.operands[1].eval(t),i;if(t.isMathOn()){if(n instanceof e.Dimension&&r instanceof e.Color){if(this.op!=="*"&&this.op!=="+")throw{type:"Operation",message:"Can't substract or divide a color from a number"};i=r,r=n,n=i}if(!n.operate)throw{type:"Operation",message:"Operation on an invalid type"};return n.operate(t,this.op,r)}return new e.Operation(this.op,[n,r],this.isSpaced)},toCSS:function(e){var t=this.isSpaced?" ":"";return this.operands[0].toCSS()+t+this.op+t+this.operands[1].toCSS()}},e.operate=function(e,t,n,r){switch(t){case"+":return n+r;case"-":return n-r;case"*":return n*r;case"/":return n/r}}}(n("../tree")),function(e){e.Paren=function(e){this.value=e},e.Paren.prototype={type:"Paren",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){return"("+this.value.toCSS(e).trim()+")"},eval:function(t){return new e.Paren(this.value.eval(t))}}}(n("../tree")),function(e){e.Quoted=function(e,t,n,r,i){this.escaped=n,this.value=t||"",this.quote=e.charAt(0),this.index=r,this.currentFileInfo=i},e.Quoted.prototype={type:"Quoted",toCSS:function(){return this.escaped?this.value:this.quote+this.value+this.quote},eval:function(t){var n=this,r=this.value.replace(/`([^`]+)`/g,function(r,i){return(new e.JavaScript(i,n.index,!0)).eval(t).value}).replace(/@\{([\w-]+)\}/g,function(r,i){var s=(new e.Variable("@"+i,n.index,n.currentFileInfo)).eval(t,!0);return s instanceof e.Quoted?s.value:s.toCSS()});return new e.Quoted(this.quote+r+this.quote,r,this.escaped,this.index)},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return t===n?0:t<n?-1:1}}}(n("../tree")),function(e){e.Rule=function(t,n,r,i,s,o){this.name=t,this.value=n instanceof e.Value?n:new e.Value([n]),this.important=r?" "+r.trim():"",this.index=i,this.currentFileInfo=s,this.inline=o||!1,t.charAt(0)==="@"?this.variable=!0:this.variable=!1},e.Rule.prototype={type:"Rule",accept:function(e){this.value=e.visit(this.value)},toCSS:function(e){if(this.variable)return"";try{return this.name+(e.compress?":":": ")+this.value.toCSS(e)+this.important+(this.inline?"":";")}catch(t){throw t.index=this.index,t.filename=this.currentFileInfo.filename,t}},eval:function(t){var n=!1;this.name==="font"&&t.strictMath===!1&&(n=!0,t.strictMath=!0);try{return new e.Rule(this.name,this.value.eval(t),this.important,this.index,this.currentFileInfo,this.inline)}finally{n&&(t.strictMath=!1)}},makeImportant:function(){return new e.Rule(this.name,this.value,"!important",this.index,this.currentFileInfo,this.inline)}}}(n("../tree")),function(e){e.Ruleset=function(e,t,n){this.selectors=e,this.rules=t,this._lookups={},this.strictImports=n},e.Ruleset.prototype={type:"Ruleset",accept:function(e){this.selectors=e.visit(this.selectors),this.rules=e.visit(this.rules)},eval:function(t){var n=this.selectors&&this.selectors.map(function(e){return e.eval(t)}),r=new e.Ruleset(n,this.rules.slice(0),this.strictImports),i;r.originalRuleset=this,r.root=this.root,r.firstRoot=this.firstRoot,r.allowImports=this.allowImports,this.debugInfo&&(r.debugInfo=this.debugInfo),t.frames.unshift(r),t.selectors||(t.selectors=[]),t.selectors.unshift(this.selectors),(r.root||r.allowImports||!r.strictImports)&&r.evalImports(t);for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Definition&&(r.rules[s].frames=t.frames.slice(0));var o=t.mediaBlocks&&t.mediaBlocks.length||0;for(var s=0;s<r.rules.length;s++)r.rules[s]instanceof e.mixin.Call&&(i=r.rules[s].eval(t).filter(function(t){return t instanceof e.Rule&&t.variable?!r.variable(t.name):!0}),r.rules.splice.apply(r.rules,[s,1].concat(i)),s+=i.length-1,r.resetCache());for(var s=0,u;s<r.rules.length;s++)u=r.rules[s],u instanceof e.mixin.Definition||(r.rules[s]=u.eval?u.eval(t):u);t.frames.shift(),t.selectors.shift();if(t.mediaBlocks)for(var s=o;s<t.mediaBlocks.length;s++)t.mediaBlocks[s].bubbleSelectors(n);return r},evalImports:function(t){var n,r;for(n=0;n<this.rules.length;n++)this.rules[n]instanceof e.Import&&(r=this.rules[n].eval(t),typeof r.length=="number"?(this.rules.splice.apply(this.rules,[n,1].concat(r)),n+=r.length-1):this.rules.splice(n,1,r),this.resetCache())},makeImportant:function(){return new e.Ruleset(this.selectors,this.rules.map(function(e){return e.makeImportant?e.makeImportant():e}),this.strictImports)},matchArgs:function(e){return!e||e.length===0},resetCache:function(){this._rulesets=null,this._variables=null,this._lookups={}},variables:function(){return this._variables?this._variables:this._variables=this.rules.reduce(function(t,n){return n instanceof e.Rule&&n.variable===!0&&(t[n.name]=n),t},{})},variable:function(e){return this.variables()[e]},rulesets:function(){return this.rules.filter(function(t){return t instanceof e.Ruleset||t instanceof e.mixin.Definition})},find:function(t,n){n=n||this;var r=[],i,s,o=t.toCSS();return o in this._lookups?this._lookups[o]:(this.rulesets().forEach(function(i){if(i!==n)for(var o=0;o<i.selectors.length;o++)if(s=t.match(i.selectors[o])){t.elements.length>i.selectors[o].elements.length?Array.prototype.push.apply(r,i.find(new e.Selector(t.elements.slice(1)),n)):r.push(i);break}}),this._lookups[o]=r)},toCSS:function(t){var n=[],r=[],i=[],s=[],o,u,a;for(var f=0;f<this.rules.length;f++){a=this.rules[f];if(a.rules||a instanceof e.Media)s.push(a.toCSS(t));else if(a instanceof e.Directive){var l=a.toCSS(t);if(a.name==="@charset"){if(t.charset){a.debugInfo&&(s.push(e.debugInfo(t,a)),s.push((new e.Comment("/* "+l.replace(/\n/g,"")+" */\n")).toCSS(t)));continue}t.charset=!0}s.push(l)}else if(a instanceof e.Comment)a.silent||(this.root?s.push(a.toCSS(t)):r.push(a.toCSS(t)));else if(a.toCSS&&!a.variable){if(this.firstRoot&&a instanceof e.Rule)throw{message:"properties must be inside selector blocks, they cannot be in the root.",index:a.index,filename:a.currentFileInfo?a.currentFileInfo.filename:null};r.push(a.toCSS(t))}else a.value&&!a.variable&&r.push(a.value.toString())}t.compress&&r.length&&(a=r[r.length-1],a.charAt(a.length-1)===";"&&(r[r.length-1]=a.substring(0,a.length-1))),s=s.join("");if(this.root)n.push(r.join(t.compress?"":"\n"));else if(r.length>0){u=e.debugInfo(t,this),o=this.paths.map(function(e){return e.map(function(e){return e.toCSS(t)}).join("").trim()}).join(t.compress?",":",\n");for(var f=r.length-1;f>=0;f--)(r[f].slice(0,2)==="/*"||i.indexOf(r[f])===-1)&&i.unshift(r[f]);r=i,n.push(u+o+(t.compress?"{":" {\n ")+r.join(t.compress?"":"\n ")+(t.compress?"}":"\n}\n"))}return n.push(s),n.join("")+(t.compress?"\n":"")},joinSelectors:function(e,t,n){for(var r=0;r<n.length;r++)this.joinSelector(e,t,n[r])},joinSelector:function(t,n,r){var i,s,o,u,a,f,l,c,h,p,d,v,m,g,y;for(i=0;i<r.elements.length;i++)f=r.elements[i],f.value==="&"&&(u=!0);if(!u){if(n.length>0)for(i=0;i<n.length;i++)t.push(n[i].concat(r));else t.push([r]);return}g=[],a=[[]];for(i=0;i<r.elements.length;i++){f=r.elements[i];if(f.value!=="&")g.push(f);else{y=[],g.length>0&&this.mergeElementsOnToSelectors(g,a);for(s=0;s<a.length;s++){l=a[s];if(n.length==0)l.length>0&&(l[0].elements=l[0].elements.slice(0),l[0].elements.push(new e.Element(f.combinator,"",0))),y.push(l);else for(o=0;o<n.length;o++)c=n[o],h=[],p=[],v=!0,l.length>0?(h=l.slice(0),m=h.pop(),d=new e.Selector(m.elements.slice(0),r.extendList),v=!1):d=new e.Selector([],r.extendList),c.length>1&&(p=p.concat(c.slice(1))),c.length>0&&(v=!1,d.elements.push(new e.Element(f.combinator,c[0].elements[0].value,0)),d.elements=d.elements.concat(c[0].elements.slice(1))),v||h.push(d),h=h.concat(p),y.push(h)}a=y,g=[]}}g.length>0&&this.mergeElementsOnToSelectors(g,a);for(i=0;i<a.length;i++)a[i].length>0&&t.push(a[i])},mergeElementsOnToSelectors:function(t,n){var r,i,s;if(n.length==0){n.push([new e.Selector(t)]);return}for(r=0;r<n.length;r++)i=n[r],i.length>0?i[i.length-1]=new e.Selector(i[i.length-1].elements.concat(t),i[i.length-1].extendList):i.push(new e.Selector(t))}}}(n("../tree")),function(e){e.Selector=function(e,t){this.elements=e,this.extendList=t||[]},e.Selector.prototype={type:"Selector",accept:function(e){this.elements=e.visit(this.elements),this.extendList=e.visit(this.extendList)},match:function(e){var t=this.elements,n=t.length,r,i,s,o;r=e.elements.slice(e.elements.length&&e.elements[0].value==="&"?1:0),i=r.length,s=Math.min(n,i);if(i===0||n<i)return!1;for(o=0;o<s;o++)if(t[o].value!==r[o].value)return!1;return!0},eval:function(t){return new e.Selector(this.elements.map(function(e){return e.eval(t)}),this.extendList.map(function(e){return e.eval(t)}))},toCSS:function(e){return this._css?this._css:(this.elements[0].combinator.value===""?this._css=" ":this._css="",this._css+=this.elements.map(function(t){return typeof t=="string"?" "+t.trim():t.toCSS(e)}).join(""),this._css)}}}(n("../tree")),function(e){e.UnicodeDescriptor=function(e){this.value=e},e.UnicodeDescriptor.prototype={type:"UnicodeDescriptor",toCSS:function(e){return this.value},eval:function(){return this} 330.14 +}}(n("../tree")),function(e){e.URL=function(e,t){this.value=e,this.currentFileInfo=t},e.URL.prototype={type:"Url",accept:function(e){this.value=e.visit(this.value)},toCSS:function(){return"url("+this.value.toCSS()+")"},eval:function(t){var n=this.value.eval(t),r;return r=this.currentFileInfo&&this.currentFileInfo.rootpath,r&&typeof n.value=="string"&&t.isPathRelative(n.value)&&(n.quote||(r=r.replace(/[\(\)'"\s]/g,function(e){return"\\"+e})),n.value=r+n.value),new e.URL(n,null)}}}(n("../tree")),function(e){e.Value=function(e){this.value=e},e.Value.prototype={type:"Value",accept:function(e){this.value=e.visit(this.value)},eval:function(t){return this.value.length===1?this.value[0].eval(t):new e.Value(this.value.map(function(e){return e.eval(t)}))},toCSS:function(e){return this.value.map(function(t){return t.toCSS(e)}).join(e.compress?",":", ")}}}(n("../tree")),function(e){e.Variable=function(e,t,n){this.name=e,this.index=t,this.currentFileInfo=n},e.Variable.prototype={type:"Variable",eval:function(t){var n,r,i=this.name;i.indexOf("@@")==0&&(i="@"+(new e.Variable(i.slice(1))).eval(t).value);if(this.evaluating)throw{type:"Name",message:"Recursive variable definition for "+i,filename:this.currentFileInfo.file,index:this.index};this.evaluating=!0;if(n=e.find(t.frames,function(e){if(r=e.variable(i))return r.value.eval(t)}))return this.evaluating=!1,n;throw{type:"Name",message:"variable "+i+" is undefined",filename:this.currentFileInfo.filename,index:this.index}}}}(n("../tree")),function(e){e.debugInfo=function(t,n){var r="";if(t.dumpLineNumbers&&!t.compress)switch(t.dumpLineNumbers){case"comments":r=e.debugInfo.asComment(n);break;case"mediaquery":r=e.debugInfo.asMediaQuery(n);break;case"all":r=e.debugInfo.asComment(n)+e.debugInfo.asMediaQuery(n)}return r},e.debugInfo.asComment=function(e){return"/* line "+e.debugInfo.lineNumber+", "+e.debugInfo.fileName+" */\n"},e.debugInfo.asMediaQuery=function(e){return"@media -sass-debug-info{filename{font-family:"+("file://"+e.debugInfo.fileName).replace(/([.:/\\])/g,function(e){return e=="\\"&&(e="/"),"\\"+e})+"}line{font-family:\\00003"+e.debugInfo.lineNumber+"}}\n"},e.find=function(e,t){for(var n=0,r;n<e.length;n++)if(r=t.call(e,e[n]))return r;return null},e.jsify=function(e){return Array.isArray(e.value)&&e.value.length>1?"["+e.value.map(function(e){return e.toCSS(!1)}).join(", ")+"]":e.toCSS(!1)}}(n("./tree")),function(e){var t=["paths","optimization","files","contents","relativeUrls","strictImports","dumpLineNumbers","compress","processImports","syncImport","mime","currentFileInfo"];e.parseEnv=function(e){r(e,this,t),this.contents||(this.contents={}),this.files||(this.files={});if(!this.currentFileInfo){var n=e&&e.filename||"input",i=n.replace(/[^\/\\]*$/,"");e&&(e.filename=null),this.currentFileInfo={filename:n,relativeUrls:this.relativeUrls,rootpath:e&&e.rootpath||"",currentDirectory:i,entryPath:i,rootFilename:n}}},e.parseEnv.prototype.toSheet=function(t){var n=new e.parseEnv(this);return n.href=t,n.type=this.mime,n};var n=["silent","verbose","compress","yuicompress","ieCompat","strictMath","strictUnits"];e.evalEnv=function(e,t){r(e,this,n),this.frames=t||[]},e.evalEnv.prototype.inParenthesis=function(){this.parensStack||(this.parensStack=[]),this.parensStack.push(!0)},e.evalEnv.prototype.outOfParenthesis=function(){this.parensStack.pop()},e.evalEnv.prototype.isMathOn=function(){return this.strictMath?this.parensStack&&this.parensStack.length:!0},e.evalEnv.prototype.isPathRelative=function(e){return!/^(?:[a-z-]+:|\/)/.test(e)};var r=function(e,t,n){if(!e)return;for(var r=0;r<n.length;r++)e.hasOwnProperty(n[r])&&(t[n[r]]=e[n[r]])}}(n("./tree")),function(e){e.visitor=function(e){this._implementation=e},e.visitor.prototype={visit:function(e){if(e instanceof Array)return this.visitArray(e);if(!e||!e.type)return e;var t="visit"+e.type,n=this._implementation[t],r,i;return n&&(r={visitDeeper:!0},i=n.call(this._implementation,e,r),this._implementation.isReplacing&&(e=i)),(!r||r.visitDeeper)&&e&&e.accept&&e.accept(this),t+="Out",this._implementation[t]&&this._implementation[t](e),e},visitArray:function(e){var t,n=[];for(t=0;t<e.length;t++){var r=this.visit(e[t]);r instanceof Array?n=n.concat(r):n.push(r)}return this._implementation.isReplacing?n:e}}}(n("./tree")),function(e){e.importVisitor=function(t,n,r){this._visitor=new e.visitor(this),this._importer=t,this._finish=n,this.env=r||new e.evalEnv,this.importCount=0},e.importVisitor.prototype={isReplacing:!0,run:function(e){var t;try{this._visitor.visit(e)}catch(n){t=n}this.isFinished=!0,this.importCount===0&&this._finish(t)},visitImport:function(t,n){var r=this,i;if(!t.css){try{i=t.evalForImport(this.env)}catch(s){s.filename||(s.index=t.index,s.filename=t.currentFileInfo.filename),t.css=!0,t.error=s}if(i&&!i.css){t=i,this.importCount++;var o=new e.evalEnv(this.env,this.env.frames.slice(0));this._importer.push(t.getPath(),t.currentFileInfo,function(n,i,s){n&&!n.filename&&(n.index=t.index,n.filename=t.currentFileInfo.filename),s&&!t.options.multiple&&(t.skip=s);var u=function(e){r.importCount--,r.importCount===0&&r.isFinished&&r._finish(e)};i?(t.root=i,(new e.importVisitor(r._importer,u,o)).run(i)):u()})}}return n.visitDeeper=!1,t},visitRule:function(e,t){return t.visitDeeper=!1,e},visitDirective:function(e,t){return this.env.frames.unshift(e),e},visitDirectiveOut:function(e){this.env.frames.shift()},visitMixinDefinition:function(e,t){return this.env.frames.unshift(e),e},visitMixinDefinitionOut:function(e){this.env.frames.shift()},visitRuleset:function(e,t){return this.env.frames.unshift(e),e},visitRulesetOut:function(e){this.env.frames.shift()},visitMedia:function(e,t){return this.env.frames.unshift(e.ruleset),e},visitMediaOut:function(e){this.env.frames.shift()}}}(n("./tree")),function(e){e.joinSelectorVisitor=function(){this.contexts=[[]],this._visitor=new e.visitor(this)},e.joinSelectorVisitor.prototype={run:function(e){return this._visitor.visit(e)},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){var n=this.contexts[this.contexts.length-1],r=[];this.contexts.push(r),e.root||(e.joinSelectors(r,n,e.selectors),e.paths=r)},visitRulesetOut:function(e){this.contexts.length=this.contexts.length-1},visitMedia:function(e,t){var n=this.contexts[this.contexts.length-1];e.ruleset.root=n.length===0||n[0].multiMedia}}}(n("./tree")),function(e){e.extendFinderVisitor=function(){this._visitor=new e.visitor(this),this.contexts=[],this.allExtendsStack=[[]]},e.extendFinderVisitor.prototype={run:function(e){return e=this._visitor.visit(e),e.allExtends=this.allExtendsStack[0],e},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitRuleset:function(t,n){if(t.root)return;var r,i,s,o=[],u;for(r=0;r<t.rules.length;r++)t.rules[r]instanceof e.Extend&&o.push(t.rules[r]);for(r=0;r<t.paths.length;r++){var a=t.paths[r],f=a[a.length-1];u=f.extendList.slice(0).concat(o).map(function(e){return e.clone()});for(i=0;i<u.length;i++)this.foundExtends=!0,s=u[i],s.findSelfSelectors(a),s.ruleset=t,i===0&&(s.firstExtendOnThisSelectorPath=!0),this.allExtendsStack[this.allExtendsStack.length-1].push(s)}this.contexts.push(t.selectors)},visitRulesetOut:function(e){e.root||(this.contexts.length=this.contexts.length-1)},visitMedia:function(e,t){e.allExtends=[],this.allExtendsStack.push(e.allExtends)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){e.allExtends=[],this.allExtendsStack.push(e.allExtends)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}},e.processExtendsVisitor=function(){this._visitor=new e.visitor(this)},e.processExtendsVisitor.prototype={run:function(t){var n=new e.extendFinderVisitor;return n.run(t),n.foundExtends?(t.allExtends=t.allExtends.concat(this.doExtendChaining(t.allExtends,t.allExtends)),this.allExtendsStack=[t.allExtends],this._visitor.visit(t)):t},doExtendChaining:function(t,n,r){var i,s,o,u=[],a,f=this,l,c,h,p;r=r||0;for(i=0;i<t.length;i++)for(s=0;s<n.length;s++){c=t[i],h=n[s];if(this.inInheritanceChain(h,c))continue;l=[h.selfSelectors[0]],o=f.findMatch(c,l),o.length&&c.selfSelectors.forEach(function(t){a=f.extendSelector(o,l,t),p=new e.Extend(h.selector,h.option,0),p.selfSelectors=a,a[a.length-1].extendList=[p],u.push(p),p.ruleset=h.ruleset,p.parents=[h,c],h.firstExtendOnThisSelectorPath&&(p.firstExtendOnThisSelectorPath=!0,h.ruleset.paths.push(a))})}if(u.length){this.extendChainCount++;if(r>100){var d="{unable to calculate}",v="{unable to calculate}";try{d=u[0].selfSelectors[0].toCSS(),v=u[0].selector.toCSS()}catch(m){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+d+":extend("+v+")"}}return u.concat(f.doExtendChaining(u,n,r+1))}return u},inInheritanceChain:function(e,t){if(e===t)return!0;if(t.parents){if(this.inInheritanceChain(e,t.parents[0]))return!0;if(this.inInheritanceChain(e,t.parents[1]))return!0}return!1},visitRule:function(e,t){t.visitDeeper=!1},visitMixinDefinition:function(e,t){t.visitDeeper=!1},visitSelector:function(e,t){t.visitDeeper=!1},visitRuleset:function(e,t){if(e.root)return;var n,r,i,s=this.allExtendsStack[this.allExtendsStack.length-1],o=[],u=this,a;for(i=0;i<s.length;i++)for(r=0;r<e.paths.length;r++){a=e.paths[r];if(a[a.length-1].extendList.length)continue;n=this.findMatch(s[i],a),n.length&&s[i].selfSelectors.forEach(function(e){o.push(u.extendSelector(n,a,e))})}e.paths=e.paths.concat(o)},findMatch:function(e,t){var n,r,i,s,o,u,a=this,f=e.selector.elements,l=[],c,h=[];for(n=0;n<t.length;n++){r=t[n];for(i=0;i<r.elements.length;i++){s=r.elements[i],(e.allowBefore||n==0&&i==0)&&l.push({pathIndex:n,index:i,matched:0,initialCombinator:s.combinator});for(u=0;u<l.length;u++)c=l[u],o=s.combinator.value,o==""&&i===0&&(o=" "),!a.isElementValuesEqual(f[c.matched].value,s.value)||c.matched>0&&f[c.matched].combinator.value!==o?c=null:c.matched++,c&&(c.finished=c.matched===f.length,c.finished&&!e.allowAfter&&(i+1<r.elements.length||n+1<t.length)&&(c=null)),c?c.finished&&(c.length=f.length,c.endPathIndex=n,c.endPathElementIndex=i+1,l.length=0,h.push(c)):(l.splice(u,1),u--)}}return h},isElementValuesEqual:function(t,n){if(typeof t=="string"||typeof n=="string")return t===n;if(t instanceof e.Attribute)return t.op!==n.op||t.key!==n.key?!1:!t.value||!n.value?t.value||n.value?!1:!0:(t=t.value.value||t.value,n=n.value.value||n.value,t===n);return!1},extendSelector:function(t,n,r){var i=0,s=0,o=[],u,a,f,l;for(u=0;u<t.length;u++)l=t[u],a=n[l.pathIndex],f=new e.Element(l.initialCombinator,r.elements[0].value,r.elements[0].index),l.pathIndex>i&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,l.pathIndex)),o.push(new e.Selector(a.elements.slice(s,l.index).concat([f]).concat(r.elements.slice(1)))),i=l.endPathIndex,s=l.endPathElementIndex,s>=a.elements.length&&(s=0,i++);return i<n.length&&s>0&&(o[o.length-1].elements=o[o.length-1].elements.concat(n[i].elements.slice(s)),s=0,i++),o=o.concat(n.slice(i,n.length)),o},visitRulesetOut:function(e){},visitMedia:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitMediaOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1},visitDirective:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},visitDirectiveOut:function(e){this.allExtendsStack.length=this.allExtendsStack.length-1}}}(n("./tree"));var o=/^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);r.env=r.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||o?"development":"production"),r.async=r.async||!1,r.fileAsync=r.fileAsync||!1,r.poll=r.poll||(o?1e3:1500);if(r.functions)for(var u in r.functions)r.tree.functions[u]=r.functions[u];var a=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);a&&(r.dumpLineNumbers=a[1]),r.watch=function(){return r.watchMode||(r.env="development",f()),this.watchMode=!0},r.unwatch=function(){return clearInterval(r.watchTimer),this.watchMode=!1},/!watch/.test(location.hash)&&r.watch();var l=null;if(r.env!="development")try{l=typeof e.localStorage=="undefined"?null:e.localStorage}catch(c){}var h=document.getElementsByTagName("link"),p=/^text\/(x-)?less$/;r.sheets=[];for(var d=0;d<h.length;d++)(h[d].rel==="stylesheet/less"||h[d].rel.match(/stylesheet/)&&h[d].type.match(p))&&r.sheets.push(h[d]);var v="";r.modifyVars=function(e){var t=v;for(var n in e)t+=(n.slice(0,1)==="@"?"":"@")+n+": "+(e[n].slice(-1)===";"?e[n]:e[n]+";");(new r.Parser(new r.tree.parseEnv(r))).parse(t,function(e,t){e?k(e,"session_cache"):S(t.toCSS(r),r.sheets[r.sheets.length-1])})},r.refresh=function(e){var t,n;t=n=new Date,g(function(e,i,s,o,u){if(e)return k(e,o.href);u.local?C("loading "+o.href+" from cache."):(C("parsed "+o.href+" successfully."),S(i.toCSS(r),o,u.lastModified)),C("css for "+o.href+" generated in "+(new Date-n)+"ms"),u.remaining===0&&C("css generated in "+(new Date-t)+"ms"),n=new Date},e),m()},r.refreshStyles=m,r.refresh(r.env==="development"),typeof define=="function"&&define.amd&&define(function(){return r})})(window); 330.15 \ No newline at end of file
331.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 331.2 +++ b/static/lf3.css Thu Jul 10 01:19:48 2014 +0200 331.3 @@ -0,0 +1,1567 @@ 331.4 +html, 331.5 +body, 331.6 +div, 331.7 +span, 331.8 +applet, 331.9 +object, 331.10 +iframe, 331.11 +h1, 331.12 +h2, 331.13 +h3, 331.14 +h4, 331.15 +h5, 331.16 +h6, 331.17 +p, 331.18 +blockquote, 331.19 +pre, 331.20 +a, 331.21 +abbr, 331.22 +acronym, 331.23 +address, 331.24 +big, 331.25 +cite, 331.26 +code, 331.27 +del, 331.28 +dfn, 331.29 +em, 331.30 +img, 331.31 +ins, 331.32 +kbd, 331.33 +q, 331.34 +s, 331.35 +samp, 331.36 +small, 331.37 +strike, 331.38 +strong, 331.39 +sub, 331.40 +sup, 331.41 +tt, 331.42 +var, 331.43 +b, 331.44 +u, 331.45 +i, 331.46 +center, 331.47 +dl, 331.48 +dt, 331.49 +dd, 331.50 +ol, 331.51 +ul, 331.52 +li, 331.53 +fieldset, 331.54 +form, 331.55 +label, 331.56 +legend, 331.57 +table, 331.58 +caption, 331.59 +tbody, 331.60 +tfoot, 331.61 +thead, 331.62 +tr, 331.63 +th, 331.64 +td, 331.65 +article, 331.66 +aside, 331.67 +canvas, 331.68 +details, 331.69 +embed, 331.70 +figure, 331.71 +figcaption, 331.72 +footer, 331.73 +header, 331.74 +hgroup, 331.75 +menu, 331.76 +nav, 331.77 +output, 331.78 +ruby, 331.79 +section, 331.80 +summary, 331.81 +time, 331.82 +mark, 331.83 +audio, 331.84 +video { 331.85 + margin: 0; 331.86 + padding: 0; 331.87 + border: 0; 331.88 + font-size: 100%; 331.89 + font: inherit; 331.90 + vertical-align: baseline; 331.91 +} 331.92 +/* HTML5 display-role reset for older browsers */ 331.93 +article, 331.94 +aside, 331.95 +details, 331.96 +figcaption, 331.97 +figure, 331.98 +footer, 331.99 +header, 331.100 +hgroup, 331.101 +menu, 331.102 +nav, 331.103 +section { 331.104 + display: block; 331.105 +} 331.106 +body { 331.107 + line-height: 1; 331.108 +} 331.109 +ol, 331.110 +ul { 331.111 + list-style: none; 331.112 +} 331.113 +blockquote, 331.114 +q { 331.115 + quotes: none; 331.116 +} 331.117 +blockquote:before, 331.118 +blockquote:after, 331.119 +q:before, 331.120 +q:after { 331.121 + content: ''; 331.122 + content: none; 331.123 +} 331.124 +table { 331.125 + border-collapse: collapse; 331.126 + border-spacing: 0; 331.127 +} 331.128 +/* end reset */ 331.129 +/* color, fonts, gaps and border radius settings */ 331.130 +.list-style { 331.131 + list-style: disc; 331.132 + padding-left: 20px; 331.133 +} 331.134 +/* 331.135 + * basic font settings 331.136 + */ 331.137 +html { 331.138 + overflow-y: scroll; 331.139 +} 331.140 +body { 331.141 + font: normal 10pt / 125% sans-serif; 331.142 + background-color: #397ab6; 331.143 + color: #000000; 331.144 + background-attachment: fixed; 331.145 +} 331.146 +.page { 331.147 + background-image: url("back50.png"); 331.148 + max-width: 1240px; 331.149 + border-radius: 0 0 2px 2px; 331.150 + margin: 0 auto; 331.151 + margin-bottom: 40px; 331.152 +} 331.153 +/* 331.154 + * messages 331.155 + */ 331.156 +.slot_notice, 331.157 +.slot_warning, 331.158 +.slot_error { 331.159 + font: bold 12pt / 125% sans-serif; 331.160 + padding: 12pt; 331.161 +} 331.162 +.slot_motd { 331.163 + background-color: #ccc; 331.164 + padding: 12pt; 331.165 +} 331.166 +.slot_notice { 331.167 + background-color: #0c0; 331.168 + color: #fff; 331.169 +} 331.170 +.slot_warning { 331.171 + background-color: #f80; 331.172 + color: #000; 331.173 +} 331.174 +.slot_error { 331.175 + background-color: #c00; 331.176 + color: #fff; 331.177 +} 331.178 +/* 331.179 + * global styles 331.180 + */ 331.181 +/* headlines */ 331.182 +h1 { 331.183 + font: bold 12pt / 125% sans-serif; 331.184 + margin-bottom: 1ex; 331.185 +} 331.186 +h1:last-child { 331.187 + margin-bottom: 0; 331.188 +} 331.189 +h2 { 331.190 + font: normal 12pt / 125% sans-serif; 331.191 +} 331.192 +h3 { 331.193 + font: bold 10pt / 125% sans-serif; 331.194 +} 331.195 +h1:first-child, 331.196 +h2:first-child, 331.197 +h3:first-child { 331.198 + margin-top: 0; 331.199 +} 331.200 +.right { 331.201 + float: right; 331.202 +} 331.203 +.left { 331.204 + float: left; 331.205 + margin-right: 9px; 331.206 +} 331.207 +/* paragraphs */ 331.208 +p { 331.209 + margin-bottom: 1.5ex; 331.210 +} 331.211 +p:last-child { 331.212 + margin-bottom: 0; 331.213 +} 331.214 +/* lists */ 331.215 +ul.ul { 331.216 + margin-left: 9px; 331.217 + margin-bottom: 1.5ex; 331.218 + list-style: disc; 331.219 + padding-left: 20px; 331.220 +} 331.221 +ul.ul li { 331.222 + margin: 3px 0; 331.223 +} 331.224 +ul.ul li:last-child { 331.225 + margin-bottom: 0; 331.226 +} 331.227 +ul.ul:last-child { 331.228 + margin-bottom: 0; 331.229 +} 331.230 +/* tables */ 331.231 +table td { 331.232 + padding: 0.3ex 0.3em; 331.233 +} 331.234 +/* links */ 331.235 +a { 331.236 + color: #222277; 331.237 +} 331.238 +a.disabled { 331.239 + color: #777777; 331.240 + cursor: default; 331.241 +} 331.242 +/* formulars */ 331.243 +form.inline { 331.244 + display: inline; 331.245 +} 331.246 +form.inline div { 331.247 + display: inline; 331.248 +} 331.249 +img { 331.250 + vertical-align: middle; 331.251 +} 331.252 +.icon16 { 331.253 + width: 16px; 331.254 + height: 16px; 331.255 +} 331.256 +.icon24 { 331.257 + width: 24px; 331.258 + height: 24px; 331.259 +} 331.260 +.icon32 { 331.261 + width: 32px; 331.262 + height: 32px; 331.263 +} 331.264 +.icon48 { 331.265 + width: 48px; 331.266 + height: 48px; 331.267 +} 331.268 +img.star { 331.269 + width: 24px; 331.270 + height: 24px; 331.271 +} 331.272 +/* 331.273 + * Avatars 331.274 + */ 331.275 +.microAvatar { 331.276 + text-wrap: nowrap; 331.277 +} 331.278 +.microAvatar img, 331.279 +img.micro_avatar { 331.280 + vertical-align: middle; 331.281 + border-radius: 2px; 331.282 + width: 24px; 331.283 + height: 24px; 331.284 +} 331.285 +img.micro_avatar.highlighted { 331.286 + margin: 0; 331.287 + border: 2px solid #ff8800; 331.288 +} 331.289 +/* 331.290 + * delegation info 331.291 + */ 331.292 +.vote_info, 331.293 +.delegation_info { 331.294 + white-space: nowrap; 331.295 + float: right; 331.296 + text-decoration: none; 331.297 + margin: -2px; 331.298 +} 331.299 +.vote_info img, 331.300 +.delegation_info img { 331.301 + vertical-align: middle; 331.302 +} 331.303 +.delegation_info img { 331.304 + border-radius: 2px; 331.305 + margin: 2px; 331.306 +} 331.307 +.delegation_info.suspended { 331.308 + opacity: 0.3; 331.309 +} 331.310 +.slot_title .delegation_info.suspended { 331.311 + opacity: 1; 331.312 +} 331.313 +/* 331.314 + * generic attributes 331.315 + */ 331.316 +.hide { 331.317 + display: none; 331.318 +} 331.319 +.head_outer { 331.320 + background-color: #000000; 331.321 + color: #ffffff; 331.322 + overflow: auto; 331.323 + margin: 0 auto; 331.324 + max-width: 1240px; 331.325 +} 331.326 +.head { 331.327 + padding: 0.3ex 0; 331.328 + margin: 0 12pt; 331.329 + /* 331.330 + * the logo and instance name 331.331 + */ 331.332 + /* 331.333 + * navigation bar 331.334 + */ 331.335 +} 331.336 +.head a { 331.337 + color: #ffffff; 331.338 +} 331.339 +.head .logo { 331.340 + display: block; 331.341 + padding: 9px 0; 331.342 + text-decoration: none; 331.343 + font: bold 10pt / 100% sans-serif; 331.344 +} 331.345 +.head .logo .liquid { 331.346 + color: #ffffff; 331.347 +} 331.348 +.head .logo .feedback { 331.349 + color: #00ee00; 331.350 +} 331.351 +.head .logo .instanceName { 331.352 + font: normal 10pt / 100% sans-serif; 331.353 + padding-top: 9px; 331.354 +} 331.355 +.head .logo:hover { 331.356 + text-decoration: underline; 331.357 +} 331.358 +.head .notifications { 331.359 + margin-left: 0.6em; 331.360 + text-decoration: none; 331.361 +} 331.362 +.head .notifications .count { 331.363 + background-color: #f00; 331.364 + color: #000; 331.365 + padding: 0.2ex 0.25em; 331.366 + border-radius: 1ex; 331.367 + vertical-align: top; 331.368 +} 331.369 +.head .notifications .icon { 331.370 + width: 24px; 331.371 + height: 24px; 331.372 +} 331.373 +.head .nav { 331.374 + float: right; 331.375 + padding-top: 6px; 331.376 +} 331.377 +.head .nav ul, 331.378 +.head .nav > ul > li:first-child { 331.379 + display: inline; 331.380 +} 331.381 +.head .nav input[name=q] { 331.382 + width: 12em; 331.383 + border-radius: 2px; 331.384 + padding: 2px; 331.385 + background-color: #000000; 331.386 + color: #ffffff; 331.387 + border: 1px solid #397ab6; 331.388 + margin-right: 0.6em; 331.389 +} 331.390 +.head .nav input[name=q]:focus { 331.391 + outline: 2px solid #397ab6; 331.392 +} 331.393 +/* 331.394 + * title 331.395 + */ 331.396 +.slot_title { 331.397 + padding-left: 12pt; 331.398 + padding-right: 12pt; 331.399 + font: bold 12pt / 125% sans-serif; 331.400 + color: #ffffff; 331.401 + padding-top: 12pt; 331.402 +} 331.403 +.slot_title a { 331.404 + color: #ffffff; 331.405 + display: inline-block; 331.406 +} 331.407 +.slot_title a.home { 331.408 + margin-right: 4px; 331.409 +} 331.410 +.slot_title a.delegation_info { 331.411 + margin-right: 0; 331.412 +} 331.413 +.slot_title .initiative, 331.414 +.slot_title a .label { 331.415 + display: none; 331.416 +} 331.417 +.slot_title .delegation_info { 331.418 + background-color: #ffffff; 331.419 + color: #000000; 331.420 + border-radius: 2px; 331.421 + padding-right: 3px; 331.422 + margin-bottom: 12pt; 331.423 +} 331.424 +.slot_title .delegation_info a { 331.425 + color: #000000; 331.426 +} 331.427 +.content { 331.428 + clear: both; 331.429 + margin: 0 12pt; 331.430 + margin-top: 12pt; 331.431 +} 331.432 +/* 331.433 + * the sidebar 331.434 + */ 331.435 +.sidebar { 331.436 + float: right; 331.437 + width: 30%; 331.438 +} 331.439 +.sidebarSection { 331.440 + background-color: #ffffff; 331.441 + border-radius: 2px; 331.442 + color: #000000; 331.443 + margin-bottom: 12pt; 331.444 + padding: 0; 331.445 +} 331.446 +.sidebarSection .sidebarHead { 331.447 + padding: 9px 9px 4.5px 9px; 331.448 + background: #ffffff; 331.449 + color: #000000; 331.450 + min-height: 20px; 331.451 +} 331.452 +.sidebarSection .sidebarHead a { 331.453 + color: #000000; 331.454 +} 331.455 +.sidebarSection .sidebarHead .icon24 { 331.456 + margin-top: -3.6px; 331.457 +} 331.458 +.sidebarSection .sidebarRow { 331.459 + clear: right; 331.460 + display: block; 331.461 + border-top: 1px solid #aaaaaa; 331.462 + padding: 4.5px 9px; 331.463 + min-height: 20px; 331.464 +} 331.465 +.sidebarSection .sidebarRow.highlighted { 331.466 + background-color: #e7f0ff; 331.467 +} 331.468 +.sidebarSection .sidebarRow.sidebarRowNarrow { 331.469 + padding: 2.25px 9px; 331.470 +} 331.471 +.sidebarSection .sidebarRow.moreLink { 331.472 + min-height: 0; 331.473 +} 331.474 +.sidebarSection h1, 331.475 +.sidebarSection h1 a, 331.476 +.sidebarSection h2, 331.477 +.sidebarSection h2 a, 331.478 +.sidebarSection h3, 331.479 +.sidebarSection h3 a { 331.480 + color: #000000; 331.481 +} 331.482 +.sidebarSection a { 331.483 + color: #222277; 331.484 +} 331.485 +.sidebarSection .areas .whenfolded { 331.486 + display: none; 331.487 +} 331.488 +.sidebarSection .areas.folded .whenunfolded { 331.489 + display: none; 331.490 +} 331.491 +.sidebarSection .areas.folded .whenfolded { 331.492 + display: block; 331.493 +} 331.494 +.sidebarSection .areas.folded .disabled { 331.495 + display: none; 331.496 +} 331.497 +.sidebarSection a.issue { 331.498 + font: bold 12pt / 125% sans-serif; 331.499 + color: #000000; 331.500 +} 331.501 +.sidebarSection ul.initiatives li { 331.502 + padding: 4.5px 9px; 331.503 + border-top: 1px solid #aaaaaa; 331.504 +} 331.505 +.sidebarSection ul.initiatives li .bargraph { 331.506 + display: block; 331.507 +} 331.508 +.sidebarSection ul.initiatives li .supporterCount { 331.509 + white-space: nowrap; 331.510 +} 331.511 +.sidebarSection ul.initiatives .revoked .initiative_name { 331.512 + text-decoration: line-through; 331.513 +} 331.514 +.sidebarSection ul.initiatives li.highlighted { 331.515 + background-color: #e7f0ff; 331.516 +} 331.517 +.sidebarSection ul.initiatives li.highlighted:last-child { 331.518 + border-radius: 0 0 2px 2px; 331.519 +} 331.520 +.sidebarSection .supporters { 331.521 + line-height: 28.799999999999997px; 331.522 +} 331.523 +.sidebarSection .supportCount { 331.524 + color: #00c000; 331.525 + font: bold 12pt / 125% sans-serif; 331.526 + float: right; 331.527 +} 331.528 +.sidebarSection .member_list .member_thumb { 331.529 + white-space: nowrap; 331.530 + overflow: hidden; 331.531 + text-overflow: ellipsis; 331.532 +} 331.533 +.sidebarSection .member_list .member_thumb img.member_image { 331.534 + width: 24px; 331.535 + height: 24px; 331.536 + vertical-align: middle; 331.537 + margin-right: 0.2em; 331.538 +} 331.539 +.sidebarSection .member_list .member_thumb.in_delegation_chain { 331.540 + font-weight: bold; 331.541 +} 331.542 +.sidebarSection > div { 331.543 + position: relative; 331.544 +} 331.545 +.sidebarSection > div:first-child { 331.546 + margin-top: 0; 331.547 + border-radius: 2px 2px 0 0; 331.548 +} 331.549 +.sidebarSection > div:last-child { 331.550 + border-radius: 0 0 2px 2px; 331.551 +} 331.552 +.sidebarSection > div:last-child:first-child { 331.553 + border-radius: 2px; 331.554 +} 331.555 +.sidebarSection a.unit { 331.556 + font: normal 12pt / 125% sans-serif; 331.557 +} 331.558 +.sidebarSection a.area { 331.559 + margin-left: 25px; 331.560 + display: block; 331.561 +} 331.562 +.sidebarSection .star { 331.563 + float: left; 331.564 +} 331.565 +.sidebarSection .delegation_info { 331.566 + margin-top: -3.6px; 331.567 + margin-bottom: 1px; 331.568 +} 331.569 +.admitted_info h1 { 331.570 + color: #00aa00; 331.571 +} 331.572 +.not_admitted_info h1, 331.573 +.revoked_info h1 { 331.574 + color: #aa0000; 331.575 +} 331.576 +.admitted_info .initiative_pie, 331.577 +.not_admitted_info .initiative_pie { 331.578 + float: right; 331.579 +} 331.580 +.admitted_info table tr th, 331.581 +.not_admitted_info table tr th { 331.582 + text-align: left; 331.583 +} 331.584 +.admitted_info table tr td, 331.585 +.not_admitted_info table tr td { 331.586 + text-align: right; 331.587 + padding: 0.3ex 0.4em; 331.588 +} 331.589 +/* 331.590 + * main area 331.591 + */ 331.592 +.main_outer { 331.593 + width: 70%; 331.594 +} 331.595 +.main { 331.596 + clear: left; 331.597 + margin-right: 12pt; 331.598 + border-radius: 2px; 331.599 + /* 331.600 + * tabs und filter 331.601 + */ 331.602 + /* 331.603 + * initiative 331.604 + */ 331.605 + /* the draft */ 331.606 +} 331.607 +.main .section .sectionHead, 331.608 +.main .section .sectionRow { 331.609 + background-color: #ffffff; 331.610 + overflow: auto; 331.611 + padding: 9px; 331.612 +} 331.613 +.main .section .sectionHead { 331.614 + background-color: #ffffff; 331.615 + color: #000000; 331.616 + margin-top: 12pt; 331.617 + border-radius: 2px 2px 0 0; 331.618 +} 331.619 +.main .section .sectionHead:first-child { 331.620 + margin-top: 0; 331.621 +} 331.622 +.main .section .sectionHead:last-child { 331.623 + border-radius: 2px; 331.624 +} 331.625 +.main .section .sectionRow { 331.626 + margin-top: 4px; 331.627 +} 331.628 +.main .section .sectionRow:last-child { 331.629 + border-radius: 0 0 2px 2px; 331.630 + margin-bottom: 12pt; 331.631 +} 331.632 +.main > h1 { 331.633 + border-bottom: 1px solid #aaaaaa; 331.634 + padding: 9px; 331.635 +} 331.636 +.main .ui_filter .ui_filter_head { 331.637 + background: #ffffff; 331.638 + color: #000000; 331.639 + padding: 0 9px 9px 9px; 331.640 + vertical-align: middle; 331.641 +} 331.642 +.main .ui_filter .ui_filter_head a { 331.643 + white-space: nowrap; 331.644 + font: normal 10pt / 150% sans-serif; 331.645 + margin-right: 0.5em; 331.646 +} 331.647 +.main .ui_filter .ui_filter_head a.active { 331.648 + font: bold 10pt / 150% sans-serif; 331.649 + text-decoration: none; 331.650 + color: #000000; 331.651 +} 331.652 +.main .ui_filter .ui_filter_head select { 331.653 + background: #ffffff; 331.654 + color: #444444; 331.655 + font: normal 10pt / 150% sans-serif; 331.656 + border: none; 331.657 + padding: 0; 331.658 + margin: 0; 331.659 +} 331.660 +.main .ui_filter .ui_filter_head select option { 331.661 + color: #000000; 331.662 +} 331.663 +.main .ui_filter .ui_filter_head select option:first-child, 331.664 +.main .ui_filter .ui_filter_head select option[value="interest_direct"], 331.665 +.main .ui_filter .ui_filter_head select option[value="interest_delegated"], 331.666 +.main .ui_filter .ui_filter_head select option[value="support_direct"], 331.667 +.main .ui_filter .ui_filter_head select option[value="support_delegated"], 331.668 +.main .ui_filter .ui_filter_head select option[value="potential_support_direct"], 331.669 +.main .ui_filter .ui_filter_head select option[value="potential_support_delegated"] { 331.670 + color: #444444; 331.671 +} 331.672 +.main .ui_filter .ui_filter_head select.active { 331.673 + color: #000000; 331.674 +} 331.675 +.main .ui_filter .ui_filter_head:first-child { 331.676 + border-radius: 2px 2px 0 0; 331.677 + padding-top: 9px; 331.678 +} 331.679 +.main .ui_filter .ui_filter_head.filter_filter { 331.680 + padding-top: 9px; 331.681 +} 331.682 +.main .ui_filter .ui_filter_head.filter_mode { 331.683 + padding-top: 9px; 331.684 + margin-bottom: 0; 331.685 + padding-bottom: 0; 331.686 +} 331.687 +.main .ui_filter .ui_filter_head.subfilter a { 331.688 + font: normal 10pt / 150% sans-serif; 331.689 +} 331.690 +.main .ui_filter .ui_filter_head.subfilter a.active { 331.691 + font: bold 10pt / 150% sans-serif; 331.692 +} 331.693 +.main .filter { 331.694 + float: right; 331.695 +} 331.696 +.main .delegation_info.suspended { 331.697 + margin: 1ex -2px -2px -2px; 331.698 +} 331.699 +.main .issues .state_info { 331.700 + font: bold 10pt / 125% sans-serif; 331.701 + color: #007700; 331.702 +} 331.703 +.main .issues .state_info.negative { 331.704 + color: #aa0000; 331.705 +} 331.706 +.main ul.initiatives li { 331.707 + margin-top: 1ex; 331.708 +} 331.709 +.main ul.initiatives li .bargraph { 331.710 + float: left; 331.711 + margin-top: 5px; 331.712 + margin-right: 0.5em; 331.713 +} 331.714 +.main ul.initiatives li .initiative_name { 331.715 + display: block; 331.716 + margin-left: 110px; 331.717 +} 331.718 +.main ul.initiatives li .rank1 .initiative_name { 331.719 + margin-left: 0; 331.720 +} 331.721 +.main ul.initiatives li .revoked .initiative_name { 331.722 + text-decoration: line-through; 331.723 +} 331.724 +.main ul.initiatives li:first-child { 331.725 + margin-top: 0; 331.726 + clear: none; 331.727 +} 331.728 +.main .events .event ul.initiatives li .initiative_name { 331.729 + margin-left: 0; 331.730 +} 331.731 +.main .member_photo { 331.732 + float: right; 331.733 +} 331.734 +.main .member_thumb.in_delegation_chain { 331.735 + font-weight: bold; 331.736 +} 331.737 +.main .support { 331.738 + color: #aaa; 331.739 + line-height: 80%; 331.740 + float: right; 331.741 + width: 102px; 331.742 +} 331.743 +.main .initiativeInfo { 331.744 + font-family: normal 10pt / 125% sans-serif; 331.745 + line-height: 24px; 331.746 + overflow: auto; 331.747 +} 331.748 +.main .initiativeInfo .support { 331.749 + margin-top: 1ex; 331.750 + float: left; 331.751 + width: auto; 331.752 +} 331.753 +.main .initiativeInfo .mySupport { 331.754 + line-height: 125%; 331.755 + min-width: 12em; 331.756 + text-align: right; 331.757 +} 331.758 +.main .initiativeInfo .initiators { 331.759 + margin-top: 1.5ex; 331.760 + margin-bottom: -1ex; 331.761 + float: left; 331.762 +} 331.763 +.main .initiativeInfo .links { 331.764 + margin-top: 1.5ex; 331.765 + margin-bottom: -1ex; 331.766 + float: right; 331.767 + clear: right; 331.768 +} 331.769 +.main .initiativeInfo .initiator_links { 331.770 + clear: right; 331.771 +} 331.772 +.main .issueInfo .links { 331.773 + margin-top: 1.5ex; 331.774 + margin-bottom: -1ex; 331.775 + float: right; 331.776 + clear: both; 331.777 +} 331.778 +.main .draft_updated_info { 331.779 + color: #007700; 331.780 +} 331.781 +.main .draft_updated_info .info { 331.782 + font: bold 10pt / 125% sans-serif; 331.783 +} 331.784 +.main .draft { 331.785 + font: normal 10pt / 125% sans-serif; 331.786 +} 331.787 +.main .draft ul { 331.788 + margin-left: 1em; 331.789 + margin-bottom: 1.5ex; 331.790 + list-style: square; 331.791 + padding-left: 1em; 331.792 +} 331.793 +.main .draft h1 { 331.794 + font: italic 10pt / 125% sans-serif; 331.795 + font-size: 125%; 331.796 + border-bottom: 1px solid #444444; 331.797 + margin-bottom: 1ex; 331.798 +} 331.799 +.main .draft h2 { 331.800 + font: normal 10pt / 125% sans-serif; 331.801 + font-size: 125%; 331.802 +} 331.803 +.main .draft h3 { 331.804 + font: normal 10pt / 125% sans-serif; 331.805 + font-size: 125%; 331.806 +} 331.807 +.main .draft h4 { 331.808 + font: normal 10pt / 125% sans-serif; 331.809 +} 331.810 +.main .draft hr { 331.811 + border: none; 331.812 + border-top: 1px solid #000000; 331.813 +} 331.814 +.main .draft b, 331.815 +.main .draft strong { 331.816 + font: italic 10pt / 125% sans-serif; 331.817 +} 331.818 +.main .draft i, 331.819 +.main .draft em { 331.820 + font: normal 10pt / 125% sans-serif; 331.821 +} 331.822 +.main form, 331.823 +.main .form { 331.824 + margin: 0; 331.825 + padding: 0; 331.826 +} 331.827 +.main form .ui_field_label, 331.828 +.main .form .ui_field_label { 331.829 + display: inline-block; 331.830 + width: 25%; 331.831 + margin: 0; 331.832 + padding: 0; 331.833 + text-align: right; 331.834 + margin-bottom: 9px; 331.835 + padding-right: 0.5%; 331.836 + vertical-align: top; 331.837 + color: #444444; 331.838 +} 331.839 +.main form input[type=text], 331.840 +.main .form input[type=text], 331.841 +.main form input[type=password], 331.842 +.main .form input[type=password], 331.843 +.main form select, 331.844 +.main .form select, 331.845 +.main form textarea, 331.846 +.main .form textarea { 331.847 + vertical-align: top; 331.848 + width: 73%; 331.849 + margin: 0; 331.850 + padding: 3px; 331.851 + border: 1px solid #444444; 331.852 + font: bold 10pt / 125% sans-serif; 331.853 + margin-bottom: 9px; 331.854 +} 331.855 +.main form input:focus, 331.856 +.main .form input:focus { 331.857 + outline: 2px solid #397ab6; 331.858 +} 331.859 +.main form .actions, 331.860 +.main .form .actions { 331.861 + margin-left: 26%; 331.862 +} 331.863 +.main form.wide input[type=text], 331.864 +.main form.wide input[type=password], 331.865 +.main form.wide select, 331.866 +.main form.wide textarea { 331.867 + width: 100%; 331.868 +} 331.869 +.issues .event .initiative_pie, 331.870 +.events .event .initiative_pie { 331.871 + clear: right; 331.872 + float: right; 331.873 +} 331.874 +.issues .event ul.initiatives .initiative_info_left, 331.875 +.events .event ul.initiatives .initiative_info_left { 331.876 + display: inline; 331.877 + margin-right: 0.5em; 331.878 +} 331.879 +.issues .event ul.initiatives .initiative_info_right, 331.880 +.events .event ul.initiatives .initiative_info_right { 331.881 + float: right; 331.882 +} 331.883 +.issues .event ul.initiatives .initiative_info_right .bargraph, 331.884 +.events .event ul.initiatives .initiative_info_right .bargraph { 331.885 + float: right; 331.886 + margin-left: 0.5em; 331.887 +} 331.888 +.issues .event ul.initiatives .result, 331.889 +.events .event ul.initiatives .result { 331.890 + color: #444444; 331.891 + margin-top: 0.5ex; 331.892 +} 331.893 +.issues .event ul.initiatives h3, 331.894 +.events .event ul.initiatives h3 { 331.895 + margin-top: 1ex; 331.896 + margin-bottom: 0; 331.897 +} 331.898 +.issues .event ul.initiatives a.initiative, 331.899 +.events .event ul.initiatives a.initiative { 331.900 + font: bold 10pt / 125% sans-serif; 331.901 +} 331.902 +.issues .event .event_info, 331.903 +.events .event .event_info { 331.904 + font: bold 10pt / 125% sans-serif; 331.905 + color: #007700; 331.906 + margin-top: 0.66ex; 331.907 + margin-bottom: 1ex; 331.908 +} 331.909 +.issues .event .event_info:last-child, 331.910 +.events .event .event_info:last-child { 331.911 + margin-bottom: 0; 331.912 +} 331.913 +.issues .event .event_info.negative, 331.914 +.events .event .event_info.negative { 331.915 + color: #aa0000; 331.916 +} 331.917 +.issues .event .event_time, 331.918 +.events .event .event_time { 331.919 + font: normal 10pt / 125% sans-serif; 331.920 + color: #444444; 331.921 +} 331.922 +.issues .event:hover .event_time, 331.923 +.events .event:hover .event_time { 331.924 + visibility: visible; 331.925 +} 331.926 +.issues .event:hover ul.initiatives div, 331.927 +.events .event:hover ul.initiatives div { 331.928 + visibility: visible; 331.929 +} 331.930 +.issues .issue_context, 331.931 +.events .issue_context { 331.932 + line-height: 24px; 331.933 + margin-bottom: 0.66ex; 331.934 +} 331.935 +.issues .issue_context .unit, 331.936 +.events .issue_context .unit { 331.937 + background-color: #777; 331.938 + color: #fff; 331.939 + padding: 1px 3px; 331.940 + border-radius: 2px; 331.941 + text-decoration: none; 331.942 +} 331.943 +.issues .issue_context .area, 331.944 +.events .issue_context .area { 331.945 + background-color: #ddd; 331.946 + color: #000; 331.947 + padding: 1px 3px; 331.948 + border-radius: 2px; 331.949 + text-decoration: none; 331.950 +} 331.951 +.issues .issue_info .issue, 331.952 +.events .issue_info .issue { 331.953 + font: bold 10pt / 125% sans-serif; 331.954 + color: #000000; 331.955 +} 331.956 +.issues img.star, 331.957 +.events img.star { 331.958 + vertical-align: middle; 331.959 + float: right; 331.960 + margin-left: 0.5em; 331.961 +} 331.962 +.issues .event.suggestion ul.initiatives li, 331.963 +.events .event.suggestion ul.initiatives li { 331.964 + margin-top: 0; 331.965 + margin-bottom: 1ex; 331.966 +} 331.967 +.issues .event.suggestion ul.initiatives li a, 331.968 +.events .event.suggestion ul.initiatives li a { 331.969 + font: normal 10pt / 125% sans-serif; 331.970 +} 331.971 +.issues .event.suggestion .suggestion, 331.972 +.events .event.suggestion .suggestion { 331.973 + font: bold 10pt / 125% sans-serif; 331.974 + overflow: hidden; 331.975 + text-overflow: ellipsis; 331.976 +} 331.977 +.suggestions .suggestion .opinion { 331.978 + float: right; 331.979 +} 331.980 +.suggestions .suggestion .opinion .must { 331.981 + background-color: #00cc00; 331.982 + color: #ffffff; 331.983 +} 331.984 +.suggestions .suggestion .opinion .should { 331.985 + background-color: #44aa44; 331.986 + color: #ffffff; 331.987 +} 331.988 +.suggestions .suggestion .opinion .shouldnot { 331.989 + background-color: #aa4444; 331.990 + color: #ffffff; 331.991 +} 331.992 +.suggestions .suggestion .opinion .mustnot { 331.993 + background-color: #cc0000; 331.994 + color: #ffffff; 331.995 +} 331.996 +.suggestions .suggestion .opinion .implemented { 331.997 + background-color: #00cc00; 331.998 + color: #ffffff; 331.999 +} 331.1000 +.suggestions .suggestion .opinion .notimplemented { 331.1001 + background-color: #cc0000; 331.1002 + color: #ffffff; 331.1003 +} 331.1004 +.suggestions .suggestion .suggestion-rating { 331.1005 + float: right; 331.1006 +} 331.1007 +.suggestions .suggestion .suggestion-text { 331.1008 + margin-top: 9px; 331.1009 + font: normal 10pt / 125% sans-serif; 331.1010 + overflow: hidden; 331.1011 + text-overflow: ellipsis; 331.1012 + position: relative; 331.1013 + z-index: 10; 331.1014 +} 331.1015 +.suggestions .suggestion .suggestion-more { 331.1016 + display: none; 331.1017 +} 331.1018 +.suggestions .suggestion .suggestion-less { 331.1019 + display: none; 331.1020 +} 331.1021 +.suggestions .suggestion .suggestionHead { 331.1022 + overflow: hidden; 331.1023 + text-overflow: ellipsis; 331.1024 +} 331.1025 +.suggestions .suggestion .rating { 331.1026 + display: none; 331.1027 + padding: 4.5px 0; 331.1028 +} 331.1029 +.suggestions .suggestion .rating .active-plus2 { 331.1030 + background-color: #00cc00; 331.1031 + color: #ffffff; 331.1032 +} 331.1033 +.suggestions .suggestion .rating .active-plus1 { 331.1034 + background-color: #44aa44; 331.1035 + color: #ffffff; 331.1036 +} 331.1037 +.suggestions .suggestion .rating .active-minus1 { 331.1038 + background-color: #aa4444; 331.1039 + color: #ffffff; 331.1040 +} 331.1041 +.suggestions .suggestion .rating .active-minus2 { 331.1042 + background-color: #cc0000; 331.1043 + color: #ffffff; 331.1044 +} 331.1045 +.suggestions .suggestion .rating .active-notfulfilled { 331.1046 + background-color: #faa; 331.1047 +} 331.1048 +.suggestions .suggestion .rating .active-fulfilled { 331.1049 + background-color: #afa; 331.1050 +} 331.1051 +.suggestions .suggestion.rateable .suggestion-more { 331.1052 + display: block; 331.1053 +} 331.1054 +.suggestions .suggestion.rateable.unfolded .rating { 331.1055 + border-top: 3px solid #397ab6; 331.1056 +} 331.1057 +.suggestions .suggestion.folded .suggestion-more { 331.1058 + display: block; 331.1059 + position: absolute; 331.1060 + bottom: 0; 331.1061 + left: 0; 331.1062 + width: 100%; 331.1063 + box-shadow: inset 0 -12ex 10ex -5ex #ffffff; 331.1064 + padding-top: 5ex; 331.1065 +} 331.1066 +.suggestions .suggestion.unfolded .suggestion-more { 331.1067 + display: none; 331.1068 +} 331.1069 +.suggestions .suggestion.unfolded .rating { 331.1070 + display: block; 331.1071 +} 331.1072 +.suggestions .suggestion.unfolded .suggestion-less { 331.1073 + margin-top: 1ex; 331.1074 + display: block; 331.1075 +} 331.1076 +.suggestions .suggestion.highlighted { 331.1077 + background-color: #e7f0ff; 331.1078 +} 331.1079 +.suggestions .suggestion.highlighted .suggestion-more { 331.1080 + box-shadow: inset 0 -12ex 10ex -5ex #e7f0ff; 331.1081 +} 331.1082 +li.raw { 331.1083 + list-style: none; 331.1084 + padding: 0; 331.1085 + margin: 0 !important; 331.1086 +} 331.1087 +.satisfiedSupporterCount { 331.1088 + color: #070; 331.1089 +} 331.1090 +.potentialSupporterCount { 331.1091 + color: #960; 331.1092 +} 331.1093 +.bargraph { 331.1094 + display: inline-block; 331.1095 + vertical-align: top; 331.1096 + height: 9px; 331.1097 +} 331.1098 +.bargraph div { 331.1099 + margin: 0; 331.1100 + padding: 0; 331.1101 + display: inline-block; 331.1102 + height: 9px; 331.1103 +} 331.1104 +.diff .diff_added { 331.1105 + background-color: #cfc; 331.1106 +} 331.1107 +.diff .diff_removed { 331.1108 + text-decoration: line-through; 331.1109 + background-color: #fcc; 331.1110 +} 331.1111 +.btn, 331.1112 +.ui_paginate_foot a { 331.1113 + text-decoration: none; 331.1114 + min-width: 2em; 331.1115 + text-align: center; 331.1116 + display: inline-block; 331.1117 + border-radius: 5px; 331.1118 + border: none; 331.1119 + font: bold 10pt / 125% sans-serif; 331.1120 + background-color: #999; 331.1121 + color: #fff !important; 331.1122 + margin-bottom: 5px; 331.1123 +} 331.1124 +.btn { 331.1125 + padding: 1ex 1em; 331.1126 +} 331.1127 +.ui_paginate_foot a { 331.1128 + padding: 0.5ex 0.5em; 331.1129 + background-color: #eee; 331.1130 + color: 000 !important; 331.1131 +} 331.1132 +.ui_paginate_foot a.active { 331.1133 + background-color: #666; 331.1134 + color: #fff !important; 331.1135 +} 331.1136 +.btn-default { 331.1137 + background-color: #47a; 331.1138 + color: #fff !important; 331.1139 +} 331.1140 +.btn:hover, 331.1141 +.btn:focus, 331.1142 +.ui_paginate_foot a:hover, 331.1143 +.ui_paginate_foot a:focus { 331.1144 + background-color: #0a0; 331.1145 + color: #fff !important; 331.1146 + cursor: pointer; 331.1147 +} 331.1148 +.btn-dangerous:hover { 331.1149 + background-color: #c00; 331.1150 + color: #fff !important; 331.1151 +} 331.1152 +.btn-link { 331.1153 + font: normal 10pt / 125% sans-serif; 331.1154 + background-color: #ffffff; 331.1155 + color: #222277; 331.1156 + border: none; 331.1157 + padding: 0; 331.1158 + margin: 0; 331.1159 + text-decoration: underline; 331.1160 + cursor: pointer; 331.1161 +} 331.1162 +/************************************************************************* 331.1163 + * Voting 331.1164 + */ 331.1165 +.main .section #voting_form .sectionRow:last-child { 331.1166 + border-radius: 0; 331.1167 + margin-bottom: 0; 331.1168 +} 331.1169 +#voting { 331.1170 + background: #ddd; 331.1171 + padding: 9px; 331.1172 + margin-top: 4px; 331.1173 + position: relative; 331.1174 + margin-bottom: 2ex; 331.1175 +} 331.1176 +#voting .approval, 331.1177 +#voting .abstention, 331.1178 +#voting .disapproval { 331.1179 + border: 2px black solid; 331.1180 + margin-bottom: 2ex; 331.1181 + padding: 1ex; 331.1182 + padding-bottom: 2ex; 331.1183 + border-radius: 2px; 331.1184 +} 331.1185 +#voting .disapproval { 331.1186 + margin-bottom: 2ex; 331.1187 +} 331.1188 +#voting .approval { 331.1189 + background-color: #9f9; 331.1190 +} 331.1191 +#voting .approval .movable { 331.1192 + background-color: #dfd; 331.1193 +} 331.1194 +#voting .abstention { 331.1195 + background-color: #ccc; 331.1196 +} 331.1197 +#voting .abstention .movable { 331.1198 + background-color: #f2f2f2; 331.1199 +} 331.1200 +#voting .disapproval { 331.1201 + background-color: #f88; 331.1202 +} 331.1203 +#voting .disapproval .movable { 331.1204 + background-color: #fbb; 331.1205 +} 331.1206 +#voting .movable { 331.1207 + position: relative; 331.1208 + border: 1px black solid; 331.1209 + margin-top: 1ex; 331.1210 + padding: 0.5ex; 331.1211 + border-radius: 2px; 331.1212 +} 331.1213 +#voting .voting_form_active .movable { 331.1214 + cursor: pointer; 331.1215 + vertical-align: middle; 331.1216 + cursor: move; 331.1217 +} 331.1218 +#voting .voting_form_active .clickable { 331.1219 + cursor: auto; 331.1220 +} 331.1221 +#voting .voting_form_active a.clickable { 331.1222 + cursor: pointer; 331.1223 +} 331.1224 +/* 331.1225 + * footer 331.1226 + */ 331.1227 +.footer { 331.1228 + text-align: center; 331.1229 + color: #ffffff; 331.1230 + background-color: #000000; 331.1231 + padding: 9px 0; 331.1232 + border: 1px solid #000; 331.1233 + border-top: none; 331.1234 +} 331.1235 +.footer a { 331.1236 + color: #ffffff; 331.1237 +} 331.1238 +.ui_paginate_head { 331.1239 + display: none; 331.1240 +} 331.1241 +.ui_paginate_foot { 331.1242 + line-height: 180%; 331.1243 +} 331.1244 +.swiper_tabs { 331.1245 + display: none; 331.1246 +} 331.1247 +#swiper_info { 331.1248 + display: none; 331.1249 +} 331.1250 +.nav .searchLink { 331.1251 + display: none; 331.1252 +} 331.1253 +@media (max-width: 767px) { 331.1254 + html body { 331.1255 + margin: 0; 331.1256 + background: #255078; 331.1257 + } 331.1258 + html body .head { 331.1259 + margin: 6pt; 331.1260 + padding: 0; 331.1261 + } 331.1262 + html body .head .logo { 331.1263 + display: block; 331.1264 + padding: 0; 331.1265 + } 331.1266 + html body .head .logo .liquid, 331.1267 + html body .head .logo .feedback { 331.1268 + font: bold 12pt / 125% sans-serif; 331.1269 + } 331.1270 + html body .head .logo .instanceName { 331.1271 + font: normal 10pt / 100% sans-serif; 331.1272 + display: block; 331.1273 + margin-left: 0; 331.1274 + } 331.1275 + html body .head .nav { 331.1276 + padding: 0; 331.1277 + } 331.1278 + html body .initiativeInfo h1 { 331.1279 + display: none; 331.1280 + } 331.1281 + html body .slot_title { 331.1282 + font: normal 12pt / 125% sans-serif; 331.1283 + padding: 0; 331.1284 + margin: 0 6pt; 331.1285 + } 331.1286 + html body .slot_title .spacer { 331.1287 + display: none; 331.1288 + } 331.1289 + html body .slot_title .unit, 331.1290 + html body .slot_title .area, 331.1291 + html body .slot_title .issue, 331.1292 + html body .slot_title .initiative, 331.1293 + html body .slot_title .member { 331.1294 + display: block; 331.1295 + margin-right: 0; 331.1296 + padding: 4px 0; 331.1297 + border-radius: 2px; 331.1298 + overflow: auto; 331.1299 + } 331.1300 + html body .slot_title .unit:before, 331.1301 + html body .slot_title .area:before, 331.1302 + html body .slot_title .issue:before, 331.1303 + html body .slot_title .initiative:before, 331.1304 + html body .slot_title .member:before { 331.1305 + content: "↳"; 331.1306 + position: relative; 331.1307 + top: -2px; 331.1308 + } 331.1309 + html body .slot_title .area { 331.1310 + margin-left: 10px; 331.1311 + } 331.1312 + html body .slot_title .issue { 331.1313 + margin-left: 20px; 331.1314 + } 331.1315 + html body .slot_title .initiative { 331.1316 + margin-left: 30px; 331.1317 + } 331.1318 + html body .slot_title a:last-child, 331.1319 + html body .slot_title .issue:last-child, 331.1320 + html body .slot_title .area:last-child, 331.1321 + html body .slot_title .unit:last-child, 331.1322 + html body .slot_title .initiative:last-child { 331.1323 + margin-bottom: 6pt; 331.1324 + } 331.1325 + html body .slot_title .unit a, 331.1326 + html body .slot_title .initiative a, 331.1327 + html body .slot_title .issue a, 331.1328 + html body .slot_title .area a { 331.1329 + margin-bottom: 0; 331.1330 + display: inline; 331.1331 + } 331.1332 + html body .slot_title a.home { 331.1333 + display: none; 331.1334 + } 331.1335 + html body .slot_title .weight { 331.1336 + float: right; 331.1337 + margin: 0; 331.1338 + } 331.1339 + html body .slot_title .delegation_info { 331.1340 + float: right; 331.1341 + display: block; 331.1342 + margin-top: -10px; 331.1343 + } 331.1344 + html body .slot_title a .label { 331.1345 + display: inline; 331.1346 + } 331.1347 + html body .slot_title .star { 331.1348 + float: right; 331.1349 + margin-left: 0.5em; 331.1350 + margin-top: -4.5px; 331.1351 + margin-bottom: -4.5px; 331.1352 + } 331.1353 + html body .slot_title > span > *:last-child { 331.1354 + font: bold 12pt / 125% sans-serif; 331.1355 + } 331.1356 + html body .page { 331.1357 + background: none; 331.1358 + margin: 0; 331.1359 + box-shadow: none; 331.1360 + } 331.1361 + html body .nav #member_menu .text { 331.1362 + display: none; 331.1363 + } 331.1364 + html body .nav form.search { 331.1365 + display: none; 331.1366 + } 331.1367 + html body .nav .notifications, 331.1368 + html body .nav .searchLink, 331.1369 + html body .nav #member_menu a { 331.1370 + vertical-align: middle; 331.1371 + display: inline-block; 331.1372 + height: 48px; 331.1373 + min-width: 35px; 331.1374 + text-align: center; 331.1375 + background-color: #000; 331.1376 + border: 1px solid #777; 331.1377 + border-radius: 2px; 331.1378 + margin: 0; 331.1379 + } 331.1380 + html body .nav .notifications img, 331.1381 + html body .nav .searchLink img, 331.1382 + html body .nav #member_menu a img { 331.1383 + margin: 0; 331.1384 + width: 48px; 331.1385 + height: 48px; 331.1386 + } 331.1387 + html body .nav .notifications { 331.1388 + padding: 12px 2px; 331.1389 + height: 24px; 331.1390 + } 331.1391 + html body .nav #member_menu a :last-child { 331.1392 + display: none; 331.1393 + } 331.1394 + html body .notifications span { 331.1395 + margin-left: -5px; 331.1396 + } 331.1397 + html body .swiper_tabs { 331.1398 + clear: both; 331.1399 + display: block; 331.1400 + overflow: auto; 331.1401 + margin: 6pt; 331.1402 + } 331.1403 + html body .swiper_tabs div { 331.1404 + display: block; 331.1405 + float: left; 331.1406 + width: 33.333%; 331.1407 + } 331.1408 + html body .swiper_tabs div a { 331.1409 + padding: 8px 0; 331.1410 + display: block; 331.1411 + text-align: center; 331.1412 + background-color: #eee; 331.1413 + } 331.1414 + html body .swiper_tabs div a.active { 331.1415 + background-color: #abe; 331.1416 + } 331.1417 + html body .swiper_tabs div:first-child a { 331.1418 + border-radius: 2px 0 0 2px; 331.1419 + } 331.1420 + html body .swiper_tabs div:last-child a { 331.1421 + border-radius: 0 2px 2px 0; 331.1422 + } 331.1423 + html body #swiper_info.active { 331.1424 + display: block; 331.1425 + font: bold 10pt / 125% sans-serif; 331.1426 + z-index: 1; 331.1427 + text-align: center; 331.1428 + width: 100%; 331.1429 + background-color: #255078; 331.1430 + color: #ffffff; 331.1431 + } 331.1432 + html body .sidebarSection { 331.1433 + margin: 0 6pt 6pt 6pt; 331.1434 + } 331.1435 + html body .main, 331.1436 + html body .extra > .section { 331.1437 + clear: none; 331.1438 + float: none; 331.1439 + width: auto; 331.1440 + margin: 0 6pt 6pt 6pt; 331.1441 + } 331.1442 + html body .main .section .sectionRow:last-child, 331.1443 + html body .extra > .section .section .sectionRow:last-child { 331.1444 + margin-bottom: 6pt; 331.1445 + } 331.1446 + html body .ui_filter_head.filter_mode { 331.1447 + float: none !important; 331.1448 + background: #ffffff !important; 331.1449 + text-align: left !important; 331.1450 + border-radius: 2px; 331.1451 + margin-bottom: 6pt !important; 331.1452 + } 331.1453 + html body .member_photo { 331.1454 + text-align: center; 331.1455 + margin-bottom: 2ex; 331.1456 + } 331.1457 + html body .member_photo .member_image_photo { 331.1458 + max-width: 600px; 331.1459 + } 331.1460 + html body #trace_content { 331.1461 + margin: 6pt 0; 331.1462 + border-radius: 0; 331.1463 + } 331.1464 + html body #trace_content ul li .trace_head { 331.1465 + padding: 6px 5px; 331.1466 + } 331.1467 + html body #trace_content ul ul { 331.1468 + padding: 5px 2px; 331.1469 + } 331.1470 +} 331.1471 +.textCenter { 331.1472 + text-align: center; 331.1473 +} 331.1474 +a.initiative { 331.1475 + text-decoration: none; 331.1476 + border-bottom: 1px solid #66c; 331.1477 +} 331.1478 +a.initiative:hover { 331.1479 + border-bottom: 1px solid #007; 331.1480 +} 331.1481 +#trace_content { 331.1482 + margin: 12pt; 331.1483 + padding: 9px; 331.1484 + border-radius: 2px; 331.1485 + background-color: #ffffff; 331.1486 +} 331.1487 +#trace_content #system_error { 331.1488 + font-family: monospace; 331.1489 +} 331.1490 +#trace_content ul li { 331.1491 + margin-top: 10px; 331.1492 +} 331.1493 +#trace_content ul li .trace_head { 331.1494 + padding: 3px 5px; 331.1495 + border-radius: 2px 2px 0 0; 331.1496 +} 331.1497 +#trace_content ul li .trace_head:last-child { 331.1498 + border-radius: 2px; 331.1499 +} 331.1500 +#trace_content ul li ul { 331.1501 + border-radius: 0 0 2px 2px; 331.1502 +} 331.1503 +#trace_content ul li:first-child { 331.1504 + margin-top: 0; 331.1505 +} 331.1506 +#trace_content ul ul { 331.1507 + padding: 10px; 331.1508 +} 331.1509 +#trace_content .trace_config > ul { 331.1510 + background-color: #eee; 331.1511 + border: 1px solid #ccc; 331.1512 +} 331.1513 +#trace_content .trace_config > .trace_head { 331.1514 + background-color: #ccc; 331.1515 + color: #000; 331.1516 +} 331.1517 +#trace_content .trace_request > ul { 331.1518 + background-color: #afa; 331.1519 +} 331.1520 +#trace_content .trace_request > .trace_head { 331.1521 + background-color: #0c0; 331.1522 +} 331.1523 +#trace_content .trace_filter > ul { 331.1524 + background-color: #ccf; 331.1525 + border: 1px solid #00c; 331.1526 + border-top: none; 331.1527 +} 331.1528 +#trace_content .trace_filter > .trace_head { 331.1529 + background-color: #00c; 331.1530 + color: #fff; 331.1531 +} 331.1532 +#trace_content .trace_view > ul { 331.1533 + background-color: #cfc; 331.1534 + border: 1px solid #0c0; 331.1535 + border-top: none; 331.1536 +} 331.1537 +#trace_content .trace_view > .trace_head { 331.1538 + background-color: #0c0; 331.1539 + color: #000; 331.1540 +} 331.1541 +#trace_content .trace_action_neutral > ul { 331.1542 + background-color: #ffa; 331.1543 + border: 1px solid #fe0; 331.1544 +} 331.1545 +#trace_content .trace_action_neutral > .trace_head { 331.1546 + background-color: #fe0; 331.1547 + color: #000; 331.1548 +} 331.1549 +#trace_content .trace_sql { 331.1550 + background-color: #fff; 331.1551 + padding: 2px 4px; 331.1552 + margin-top: 8px; 331.1553 +} 331.1554 +#trace_content .trace_error { 331.1555 + background-color: #faa; 331.1556 + color: #000; 331.1557 + font-weight: bold; 331.1558 + border: 1px solid #c00; 331.1559 +} 331.1560 +#trace_content .trace_exectime { 331.1561 + background-color: #ccc; 331.1562 + font-weight: bold; 331.1563 + border-radius: 2px; 331.1564 +} 331.1565 +#trace_content .time { 331.1566 + float: right; 331.1567 +} 331.1568 +#trace_content .total_duration { 331.1569 + font-weight: bold; 331.1570 +}
332.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 332.2 +++ b/static/lf3.less Thu Jul 10 01:19:48 2014 +0200 332.3 @@ -0,0 +1,1935 @@ 332.4 +html, body, div, span, applet, object, iframe, 332.5 +h1, h2, h3, h4, h5, h6, p, blockquote, pre, 332.6 +a, abbr, acronym, address, big, cite, code, 332.7 +del, dfn, em, img, ins, kbd, q, s, samp, 332.8 +small, strike, strong, sub, sup, tt, var, 332.9 +b, u, i, center, 332.10 +dl, dt, dd, ol, ul, li, 332.11 +fieldset, form, label, legend, 332.12 +table, caption, tbody, tfoot, thead, tr, th, td, 332.13 +article, aside, canvas, details, embed, 332.14 +figure, figcaption, footer, header, hgroup, 332.15 +menu, nav, output, ruby, section, summary, 332.16 +time, mark, audio, video { 332.17 + margin: 0; 332.18 + padding: 0; 332.19 + border: 0; 332.20 + font-size: 100%; 332.21 + font: inherit; 332.22 + vertical-align: baseline; 332.23 +} 332.24 +/* HTML5 display-role reset for older browsers */ 332.25 +article, aside, details, figcaption, figure, 332.26 +footer, header, hgroup, menu, nav, section { 332.27 + display: block; 332.28 +} 332.29 +body { 332.30 + line-height: 1; 332.31 +} 332.32 +ol, ul { 332.33 + list-style: none; 332.34 +} 332.35 +blockquote, q { 332.36 + quotes: none; 332.37 +} 332.38 +blockquote:before, blockquote:after, 332.39 +q:before, q:after { 332.40 + content: ''; 332.41 + content: none; 332.42 +} 332.43 +table { 332.44 + border-collapse: collapse; 332.45 + border-spacing: 0; 332.46 +} 332.47 + 332.48 +/* end reset */ 332.49 + 332.50 + 332.51 +/* color, fonts, gaps and border radius settings */ 332.52 + 332.53 +@body-bg-color: #397ab6; 332.54 +@body-color: #fff; 332.55 +@footer-bg-color: #000; 332.56 +@footer-color: #fff; 332.57 +@page-bg-color: #ddd; 332.58 +@mobile-bg-color: #255078; 332.59 +@head-bg-color: #000; 332.60 +@head-color: #fff; 332.61 +@head-second-color: #0e0; 332.62 +@head-link-color: #fff; 332.63 +@main-bg-color: #fff; 332.64 +@main-color: #000; 332.65 +@main-second-color: #444; 332.66 +@main-event-color: #070; 332.67 +@main-negative-event-color: #a00; 332.68 +@main-head-bg-color: #fff; 332.69 +@main-head-color: #000; 332.70 +@main-link-color: #227; 332.71 +@main-seperator-color: #aaa; 332.72 +@main-highlight-bg-color: #e7f0ff; 332.73 +@main-supported-bg-color: #fa2; 332.74 +@main-satisfied-bg-color: #282; 332.75 +@sidebar-bg-color: #fff; 332.76 +@sidebar-color: #000; 332.77 +@sidebar-head-bg-color: @main-head-bg-color; 332.78 +@sidebar-head-color: @main-head-color; 332.79 +@sidebar-link-color: #227; 332.80 +@sidebar-hr-color: #777; 332.81 +@disabled-color: #777; 332.82 +@admitted-color: #0a0; 332.83 +@not-admitted-color: #a00; 332.84 + 332.85 +@delegation-bg-color: #fff; 332.86 +@delegation-color: #000; 332.87 +@delegation-active-border-color: #f80; 332.88 + 332.89 +@must-bg-color: #0c0; 332.90 +@must-color: #fff; 332.91 +@should-bg-color: #4a4; 332.92 +@should-color: #fff; 332.93 +@shouldnot-bg-color: #a44; 332.94 +@shouldnot-color: #fff; 332.95 +@mustnot-bg-color: #c00; 332.96 +@mustnot-color: #fff; 332.97 + 332.98 +@implemented-bg-color: #0c0; 332.99 +@implemented-color: #fff; 332.100 +@notimplemented-bg-color: #c00; 332.101 +@notimplemented-color: #fff; 332.102 + 332.103 +@font: sans-serif; 332.104 +@size-normal: 10pt; 332.105 +@size-big: 12pt; 332.106 +@line-height: 125%; 332.107 + 332.108 + 332.109 + 332.110 +@logo-font: bold @size-normal e('/') 100% @font; 332.111 +@instance-font: normal @size-normal e('/') 100% @font; 332.112 +@mobile-logo-font: bold @size-big e('/') @line-height @font; 332.113 +@mobile-instance-font: normal @size-normal e('/') 100% @font; 332.114 + 332.115 +@title-font: bold @size-big e('/') @line-height @font; 332.116 + 332.117 +@main-font: normal @size-normal e('/') @line-height @font; 332.118 +@event-font: bold @size-normal e('/') @line-height @font; 332.119 + 332.120 +@tabs-font: normal @size-normal e('/') @line-height @font; 332.121 +@tabs-active-font: bold @size-big e('/') @line-height @font; 332.122 + 332.123 +@filter-font: normal @size-normal e('/') 150% @font; 332.124 +@filter-active-font: bold @size-normal e('/') 150% @font; 332.125 + 332.126 +@subfilter-font: @filter-font; 332.127 +@subfilter-active-font: @filter-active-font; 332.128 + 332.129 +@head1-font: bold @size-big e('/') @line-height @font; 332.130 +@head2-font: normal @size-big e('/') @line-height @font; 332.131 +@head3-font: bold @size-normal e('/') @line-height @font; 332.132 + 332.133 +@btn-font: bold @size-normal e('/') @line-height @font; 332.134 + 332.135 +@usertext-font: normal @size-normal e('/') @line-height @font; 332.136 +@usertext-italic-font: italic @size-normal e('/') @line-height @font; 332.137 +@usertext-bold-font: normal @size-normal e('/') @line-height @font; 332.138 + 332.139 + 332.140 + 332.141 +@main-width: 70%; 332.142 + 332.143 +@pad: 9px; 332.144 +@grid: 12pt; 332.145 + 332.146 +@paragraph-margin: 1.5ex; 332.147 + 332.148 +@border-radius: 2px; 332.149 +@btn-border-radius: 5px; 332.150 + 332.151 +.list-style { 332.152 + list-style: disc; 332.153 + padding-left: 20px; 332.154 +} 332.155 + 332.156 +@micro-avatar-size: 24px; 332.157 + 332.158 +/* 332.159 + * basic font settings 332.160 + */ 332.161 + 332.162 +html { 332.163 + overflow-y: scroll; 332.164 +} 332.165 + 332.166 +body { 332.167 + font: @main-font; 332.168 + background-color: @body-bg-color; 332.169 + //background-image: url( "back2.png" ); 332.170 + color: @main-color; 332.171 + background-attachment: fixed; 332.172 +} 332.173 + 332.174 +.page { 332.175 + background-image: url( "back50.png" ); 332.176 + max-width: 1240px; 332.177 + border-radius: 0 0 @border-radius @border-radius; 332.178 + margin: 0 auto; 332.179 + margin-bottom: 40px; 332.180 +} 332.181 + 332.182 +/* 332.183 + * messages 332.184 + */ 332.185 + 332.186 +.slot_notice, 332.187 +.slot_warning, 332.188 +.slot_error { 332.189 + font: @head1-font; 332.190 + padding: @grid; 332.191 +} 332.192 + 332.193 +.slot_motd { 332.194 + background-color: #ccc; 332.195 + padding: @grid; 332.196 +} 332.197 + 332.198 +.slot_notice { 332.199 + background-color: #0c0; 332.200 + color: #fff; 332.201 +} 332.202 + 332.203 +.slot_warning { 332.204 + background-color: #f80; 332.205 + color: #000; 332.206 +} 332.207 + 332.208 +.slot_error { 332.209 + background-color: #c00; 332.210 + color: #fff; 332.211 +} 332.212 + 332.213 +/* 332.214 + * global styles 332.215 + */ 332.216 + 332.217 +/* headlines */ 332.218 +h1 { 332.219 + font: @head1-font; 332.220 + margin-bottom: 1ex; 332.221 +} 332.222 + 332.223 +h1:last-child { 332.224 + margin-bottom: 0; 332.225 +} 332.226 + 332.227 +h2 { 332.228 + font: @head2-font; 332.229 +} 332.230 + 332.231 +h3 { 332.232 + font: @head3-font; 332.233 +} 332.234 + 332.235 +h1:first-child, 332.236 +h2:first-child, 332.237 +h3:first-child { 332.238 + margin-top: 0; 332.239 +} 332.240 + 332.241 +.right { 332.242 + float: right; 332.243 +} 332.244 + 332.245 +.left { 332.246 + float: left; 332.247 + margin-right: @pad; 332.248 +} 332.249 + 332.250 +/* paragraphs */ 332.251 +p { 332.252 + margin-bottom: @paragraph-margin; 332.253 +} 332.254 + 332.255 +p:last-child { 332.256 + margin-bottom: 0; 332.257 +} 332.258 + 332.259 +/* lists */ 332.260 +ul.ul { 332.261 + margin-left: @pad; 332.262 + margin-bottom: @paragraph-margin; 332.263 + .list-style; 332.264 + li { 332.265 + margin: @pad/3 0; 332.266 + } 332.267 + 332.268 + li:last-child { 332.269 + margin-bottom: 0; 332.270 + } 332.271 +} 332.272 + 332.273 +ul.ul:last-child { 332.274 + margin-bottom: 0; 332.275 +} 332.276 + 332.277 + 332.278 +/* tables */ 332.279 + 332.280 +table { 332.281 + 332.282 + td { 332.283 + 332.284 + padding: 0.3ex 0.3em; 332.285 + 332.286 + } 332.287 + 332.288 +} 332.289 + 332.290 +/* links */ 332.291 + 332.292 +a { 332.293 + color: @main-link-color; 332.294 +} 332.295 + 332.296 +a.disabled { 332.297 + color: @disabled-color; 332.298 + cursor: default; 332.299 +} 332.300 + 332.301 +/* formulars */ 332.302 +form.inline { 332.303 + display: inline; 332.304 + div { 332.305 + display: inline; 332.306 + } 332.307 +} 332.308 + 332.309 +img { 332.310 + vertical-align: middle; 332.311 +} 332.312 + 332.313 + 332.314 +.icon16 { 332.315 + width: 16px; 332.316 + height: 16px; 332.317 +} 332.318 + 332.319 +.icon24 { 332.320 + width: 24px; 332.321 + height: 24px; 332.322 +} 332.323 +.icon32 { 332.324 + width: 32px; 332.325 + height: 32px; 332.326 +} 332.327 +.icon48 { 332.328 + width: 48px; 332.329 + height: 48px; 332.330 +} 332.331 + 332.332 + 332.333 +img.star { 332.334 + width: 24px; 332.335 + height: 24px; 332.336 +} 332.337 + 332.338 +/* 332.339 + * Avatars 332.340 + */ 332.341 + 332.342 +.microAvatar { 332.343 + text-wrap: nowrap; 332.344 +} 332.345 + 332.346 +.microAvatar img, 332.347 +img.micro_avatar { 332.348 + vertical-align: middle; 332.349 + border-radius: 2px; 332.350 + width: @micro-avatar-size; 332.351 + height: @micro-avatar-size; 332.352 +} 332.353 + 332.354 +img.micro_avatar.highlighted { 332.355 + margin: 0; 332.356 + border: 2px solid @delegation-active-border-color; 332.357 +} 332.358 + 332.359 + 332.360 +/* 332.361 + * delegation info 332.362 + */ 332.363 + 332.364 +.vote_info, 332.365 +.delegation_info { 332.366 + white-space: nowrap; 332.367 + float: right; 332.368 + text-decoration: none; 332.369 + img { 332.370 + vertical-align: middle; 332.371 + } 332.372 + margin: -2px; 332.373 +} 332.374 + 332.375 +.delegation_info img { 332.376 + border-radius: @border-radius; 332.377 + margin: 2px; 332.378 +} 332.379 + 332.380 +.delegation_info.suspended { 332.381 + opacity: 0.3; 332.382 +} 332.383 + 332.384 +.slot_title .delegation_info.suspended { 332.385 + opacity: 1; 332.386 +} 332.387 + 332.388 +/* 332.389 + * generic attributes 332.390 + */ 332.391 + 332.392 +.hide { 332.393 + display: none; 332.394 +} 332.395 +.head_outer { 332.396 + background-color: @head-bg-color; 332.397 + color: @head-color; 332.398 + overflow: auto; 332.399 + margin: 0 auto; 332.400 + max-width: 1240px; 332.401 +} 332.402 +.head { 332.403 + padding: 0.3ex 0; 332.404 + margin: 0 @grid; 332.405 + a { 332.406 + color: @head-link-color; 332.407 + } 332.408 + 332.409 + /* 332.410 + * the logo and instance name 332.411 + */ 332.412 + .logo { 332.413 + display: block; 332.414 + padding: @pad 0; 332.415 + text-decoration: none; 332.416 + font: @logo-font; 332.417 + 332.418 + .liquid { 332.419 + color: @head-color; 332.420 + } 332.421 + 332.422 + .feedback { 332.423 + color: @head-second-color; 332.424 + } 332.425 + .instanceName { 332.426 + font: @instance-font; 332.427 + padding-top: @pad; 332.428 + } 332.429 + } 332.430 + .logo:hover { 332.431 + text-decoration: underline; 332.432 + } 332.433 + 332.434 + 332.435 + 332.436 + .notifications { 332.437 + margin-left: 0.6em; 332.438 + text-decoration: none; 332.439 + 332.440 + .count { 332.441 + background-color: #f00; 332.442 + color: #000; 332.443 + padding: 0.2ex 0.25em; 332.444 + border-radius: 1ex; 332.445 + vertical-align: top; 332.446 + } 332.447 + 332.448 + .icon { 332.449 + width: 24px; 332.450 + height: 24px; 332.451 + } 332.452 + } 332.453 + 332.454 + /* 332.455 + * navigation bar 332.456 + */ 332.457 + .nav { 332.458 + float: right; 332.459 + padding-top: @pad - 3px; 332.460 + 332.461 + ul, > ul > li:first-child { 332.462 + display: inline; 332.463 + } 332.464 + 332.465 + input[name=q] { 332.466 + width: 12em; 332.467 + border-radius: @border-radius; 332.468 + padding: 2px; 332.469 + background-color: @head-bg-color; 332.470 + color: @head-color; 332.471 + border: 1px solid @body-bg-color; 332.472 + margin-right: 0.6em; 332.473 + } 332.474 + input[name=q]:focus { 332.475 + outline: 2px solid @body-bg-color; 332.476 + } 332.477 + 332.478 + #member_menu a span { 332.479 + margin-left: 5px; 332.480 + } 332.481 + 332.482 + } 332.483 + 332.484 +} 332.485 + 332.486 +/* 332.487 + * title 332.488 + */ 332.489 +.slot_title { 332.490 + 332.491 + padding-left: @grid; 332.492 + padding-right: @grid; 332.493 + font: @title-font; 332.494 + color: @body-color; 332.495 + padding-top: @grid; 332.496 + 332.497 + a { 332.498 + color: @body-color; 332.499 + display: inline-block; 332.500 + } 332.501 + 332.502 + a.home { 332.503 + margin-right: 4px; 332.504 + } 332.505 + 332.506 + a.delegation_info { 332.507 + margin-right: 0; 332.508 + } 332.509 + 332.510 + .initiative, 332.511 + a .label { 332.512 + display: none; 332.513 + } 332.514 + 332.515 + .delegation_info { 332.516 + background-color: @main-bg-color; 332.517 + color: @main-color; 332.518 + border-radius: @border-radius; 332.519 + padding-right: 3px; 332.520 + margin-bottom: @grid; 332.521 + a { 332.522 + color: @main-color; 332.523 + } 332.524 + } 332.525 +} 332.526 + 332.527 +.content { 332.528 + clear: both; 332.529 + margin: 0 @grid; 332.530 + margin-top: @grid; 332.531 +} 332.532 + 332.533 +/* 332.534 + * the sidebar 332.535 + */ 332.536 + 332.537 +.sidebar { 332.538 + float: right; 332.539 + width: 100% - @main-width; 332.540 +} 332.541 + 332.542 +.sidebarSection { 332.543 + background-color: @sidebar-bg-color; 332.544 + border-radius: @border-radius; 332.545 + color: @sidebar-color; 332.546 + margin-bottom: @grid; 332.547 + padding: 0; 332.548 + 332.549 + .sidebarHead { 332.550 + padding: @pad @pad @pad / 2 @pad; 332.551 + background: @sidebar-head-bg-color; 332.552 + color: @sidebar-head-color; 332.553 + 332.554 + a { 332.555 + color: @sidebar-head-color; 332.556 + } 332.557 + min-height: 20px; 332.558 + 332.559 + .icon24 { 332.560 + margin-top: -@pad/2.5; 332.561 + } 332.562 + } 332.563 + 332.564 + .sidebarRow { 332.565 + clear: right; 332.566 + display: block; 332.567 + border-top: 1px solid @main-seperator-color; 332.568 + padding: @pad/2 @pad; 332.569 + min-height: 20px; 332.570 + } 332.571 + .sidebarRow.highlighted { 332.572 + background-color: @main-highlight-bg-color; 332.573 + } 332.574 + 332.575 + .sidebarRow.sidebarRowNarrow { 332.576 + padding: @pad / 4 @pad; 332.577 + } 332.578 + 332.579 + .sidebarRow.moreLink { 332.580 + min-height: 0; 332.581 + } 332.582 + 332.583 + h1, h1 a, 332.584 + h2, h2 a, 332.585 + h3, h3 a { 332.586 + color: @sidebar-head-color; 332.587 + } 332.588 + 332.589 + a { 332.590 + color: @sidebar-link-color; 332.591 + } 332.592 + 332.593 + .areas { 332.594 + .whenfolded { 332.595 + display: none; 332.596 + } 332.597 + } 332.598 + 332.599 + .areas.folded { 332.600 + .whenunfolded { 332.601 + display: none; 332.602 + } 332.603 + .whenfolded { 332.604 + display: block; 332.605 + } 332.606 + .disabled { 332.607 + display: none; 332.608 + } 332.609 + } 332.610 + 332.611 + 332.612 + a.issue { 332.613 + font: @head1-font; 332.614 + color: @main-color; 332.615 + } 332.616 + 332.617 + ul.initiatives { 332.618 + li { 332.619 + padding: @pad/2 @pad; 332.620 + .bargraph { 332.621 + display: block; 332.622 + } 332.623 + .supporterCount { 332.624 + white-space: nowrap; 332.625 + } 332.626 + border-top: 1px solid @main-seperator-color; 332.627 + } 332.628 + .revoked .initiative_name { 332.629 + text-decoration: line-through; 332.630 + } 332.631 + 332.632 + li.highlighted { 332.633 + background-color: @main-highlight-bg-color; 332.634 + } 332.635 + li.highlighted:last-child{ 332.636 + border-radius: 0 0 @border-radius @border-radius; 332.637 + } 332.638 + } 332.639 + 332.640 + .supporters { 332.641 + line-height: @micro-avatar-size * 1.2; 332.642 + } 332.643 + 332.644 + .supportCount { 332.645 + color: #00c000; 332.646 + font: @head1-font; 332.647 + float: right; 332.648 + } 332.649 + 332.650 + .member_list { 332.651 + 332.652 + .member_thumb { 332.653 + white-space: nowrap; 332.654 + overflow: hidden; 332.655 + text-overflow: ellipsis; 332.656 + 332.657 + img.member_image { 332.658 + width: 24px; 332.659 + height: 24px; 332.660 + vertical-align: middle; 332.661 + margin-right: 0.2em; 332.662 + } 332.663 + 332.664 + } 332.665 + 332.666 + .member_thumb.in_delegation_chain { 332.667 + font-weight: bold; 332.668 + } 332.669 + } 332.670 + 332.671 + 332.672 + > div { 332.673 + position: relative; 332.674 + } 332.675 + 332.676 + > div:first-child { 332.677 + margin-top: 0; 332.678 + border-radius: @border-radius @border-radius 0 0; 332.679 + } 332.680 + 332.681 + > div:last-child { 332.682 + border-radius: 0 0 @border-radius @border-radius; 332.683 + } 332.684 + 332.685 + > div:last-child:first-child { 332.686 + border-radius: @border-radius; 332.687 + } 332.688 + 332.689 + 332.690 + a.unit { 332.691 + font: @head2-font; 332.692 + } 332.693 + 332.694 + a.area { 332.695 + margin-left: 25px; 332.696 + display: block; 332.697 + } 332.698 + 332.699 + .star { 332.700 + float: left; 332.701 + } 332.702 + 332.703 + .delegation_info { 332.704 + margin-top: -@pad/2.5; 332.705 + margin-bottom: 1px; 332.706 + } 332.707 +} 332.708 + 332.709 +.admitted_info h1 { 332.710 + color: @admitted-color; 332.711 +} 332.712 + 332.713 +.not_admitted_info, .revoked_info { 332.714 + h1 { 332.715 + color: @not-admitted-color; 332.716 + } 332.717 +} 332.718 + 332.719 +.admitted_info, 332.720 +.not_admitted_info { 332.721 + 332.722 + .initiative_pie { 332.723 + float: right; 332.724 + } 332.725 + 332.726 + table { 332.727 + tr { 332.728 + th { 332.729 + text-align: left; 332.730 + } 332.731 + td { 332.732 + text-align: right; 332.733 + padding: 0.3ex 0.4em; 332.734 + } 332.735 + } 332.736 + } 332.737 +} 332.738 + 332.739 + 332.740 + 332.741 + 332.742 +/* 332.743 + * main area 332.744 + */ 332.745 + 332.746 +.main_outer { 332.747 + width: @main-width; 332.748 +} 332.749 + 332.750 + 332.751 +.main { 332.752 + 332.753 + clear: left; 332.754 + margin-right: @grid; 332.755 + border-radius: @border-radius; 332.756 + 332.757 + .section { 332.758 + 332.759 + .sectionHead, .sectionRow { 332.760 + background-color: @main-bg-color; 332.761 + overflow: auto; 332.762 + padding: @pad; 332.763 + } 332.764 + 332.765 + .sectionHead { 332.766 + background-color: @main-head-bg-color; 332.767 + color: @main-head-color; 332.768 + margin-top: @grid; 332.769 + border-radius: @border-radius @border-radius 0 0; 332.770 + } 332.771 + 332.772 + .sectionHead:first-child { 332.773 + margin-top: 0; 332.774 + } 332.775 + 332.776 + .sectionHead:last-child { 332.777 + border-radius: @border-radius; 332.778 + } 332.779 + 332.780 + 332.781 + .sectionRow { 332.782 + margin-top: 4px; 332.783 + } 332.784 + 332.785 + .sectionRow:last-child { 332.786 + border-radius: 0 0 @border-radius @border-radius; 332.787 + margin-bottom: @grid; 332.788 + } 332.789 + 332.790 + 332.791 + } 332.792 + 332.793 + .ui_tabs_links { 332.794 + } 332.795 + 332.796 + > h1 { 332.797 + border-bottom: 1px solid @main-seperator-color; 332.798 + padding: @pad; 332.799 + } 332.800 + 332.801 + /* 332.802 + * tabs und filter 332.803 + */ 332.804 + 332.805 + .ui_filter { 332.806 + .ui_filter_head { 332.807 + background: @main-head-bg-color; 332.808 + color: @main-head-color; 332.809 + padding: 0 @pad @pad @pad; 332.810 + vertical-align: middle; 332.811 + a { 332.812 + white-space: nowrap; 332.813 + font: @filter-font; 332.814 + margin-right: 0.5em; 332.815 + } 332.816 + a.active { 332.817 + font: @filter-active-font; 332.818 + text-decoration: none; 332.819 + color: @main-head-color; 332.820 + } 332.821 + select { 332.822 + background: @main-bg-color; 332.823 + color: @main-second-color; 332.824 + font: @filter-font; 332.825 + border: none; 332.826 + padding: 0; 332.827 + margin: 0; 332.828 + 332.829 + option { 332.830 + color: @main-color; 332.831 + } 332.832 + option:first-child, 332.833 + option[value="interest_direct"], 332.834 + option[value="interest_delegated"], 332.835 + option[value="support_direct"], 332.836 + option[value="support_delegated"], 332.837 + option[value="potential_support_direct"], 332.838 + option[value="potential_support_delegated"] { 332.839 + color: @main-second-color; 332.840 + } 332.841 + } 332.842 + select.active { 332.843 + color: @main-color; 332.844 + } 332.845 + } 332.846 + .ui_filter_head:first-child { 332.847 + border-radius: @border-radius @border-radius 0 0; 332.848 + padding-top: @pad; 332.849 + } 332.850 + .ui_filter_head.filter_filter { 332.851 + padding-top: @pad; 332.852 + } 332.853 + 332.854 + .ui_filter_head.filter_mode { 332.855 + padding-top: @pad; 332.856 + margin-bottom: 0; 332.857 + padding-bottom: 0; 332.858 + } 332.859 + .ui_filter_head.subfilter { 332.860 + a { 332.861 + font: @subfilter-font; 332.862 + } 332.863 + a.active { 332.864 + font: @subfilter-active-font; 332.865 + } 332.866 + } 332.867 + } 332.868 + 332.869 + .filter { 332.870 + float: right; 332.871 + } 332.872 + 332.873 + .delegation_info.suspended { 332.874 + margin: 1ex -2px -2px -2px; 332.875 + } 332.876 + 332.877 + 332.878 + .issues { 332.879 + .state_info { 332.880 + font: @event-font; 332.881 + color: @main-event-color; 332.882 + } 332.883 + .state_info.negative { 332.884 + color: @main-negative-event-color; 332.885 + } 332.886 + } 332.887 + 332.888 + ul.initiatives { 332.889 + li { 332.890 + margin-top: 1ex; 332.891 + 332.892 + .bargraph { 332.893 + float: left; 332.894 + margin-top: 5px; 332.895 + margin-right: 0.5em; 332.896 + } 332.897 + 332.898 + .initiative_name { 332.899 + display: block; 332.900 + margin-left: 110px; 332.901 + } 332.902 + 332.903 + .rank1 .initiative_name { 332.904 + margin-left: 0; 332.905 + } 332.906 + 332.907 + .revoked .initiative_name { 332.908 + text-decoration: line-through; 332.909 + } 332.910 + 332.911 + } 332.912 + 332.913 + li:first-child { 332.914 + margin-top: 0; 332.915 + clear: none; 332.916 + } 332.917 + 332.918 + } 332.919 + 332.920 + .events .event ul.initiatives li .initiative_name { 332.921 + margin-left: 0; 332.922 + } 332.923 + 332.924 + .member_photo { 332.925 + float: right; 332.926 + } 332.927 + 332.928 + .member_thumb.in_delegation_chain { 332.929 + font-weight: bold; 332.930 + } 332.931 + 332.932 + 332.933 + 332.934 + /* 332.935 + * initiative 332.936 + */ 332.937 + 332.938 + 332.939 + .support { 332.940 + color: #aaa; 332.941 + line-height: 80%; 332.942 + float: right; 332.943 + width: 102px; 332.944 + } 332.945 + 332.946 + .initiativeInfo { 332.947 + font-family: @main-font; 332.948 + line-height: @micro-avatar-size; 332.949 + overflow: auto; 332.950 + 332.951 + .support { 332.952 + margin-top: 1ex; 332.953 + float: left; 332.954 + width: auto; 332.955 + } 332.956 + 332.957 + .mySupport { 332.958 + line-height: 125%; 332.959 + min-width: 12em; 332.960 + text-align: right; 332.961 + } 332.962 + 332.963 + .initiators { 332.964 + margin-top: 1.5ex; 332.965 + margin-bottom: -1ex; 332.966 + float: left; 332.967 + } 332.968 + 332.969 + .links { 332.970 + margin-top: 1.5ex; 332.971 + margin-bottom: -1ex; 332.972 + float: right; 332.973 + clear: right; 332.974 + } 332.975 + 332.976 + .initiator_links { 332.977 + clear: right; 332.978 + } 332.979 + 332.980 + } 332.981 + 332.982 + .issueInfo { 332.983 + .links { 332.984 + margin-top: 1.5ex; 332.985 + margin-bottom: -1ex; 332.986 + float: right; 332.987 + clear: both; 332.988 + } 332.989 + } 332.990 + 332.991 + .draft_updated_info { 332.992 + color: @main-event-color; 332.993 + 332.994 + .info { 332.995 + font: @head3-font; 332.996 + } 332.997 + } 332.998 + 332.999 + /* the draft */ 332.1000 + .draft { 332.1001 + font: @usertext-font; 332.1002 + 332.1003 + ul { 332.1004 + margin-left: 1em; 332.1005 + margin-bottom: @paragraph-margin; 332.1006 + list-style: square; 332.1007 + padding-left: 1em; 332.1008 + } 332.1009 + 332.1010 + h1 { 332.1011 + font: @usertext-italic-font; 332.1012 + font-size: 125%; 332.1013 + border-bottom: 1px solid @main-second-color; 332.1014 + margin-bottom: 1ex; 332.1015 + } 332.1016 + 332.1017 + h2 { 332.1018 + font: @usertext-bold-font; 332.1019 + font-size: 125%; 332.1020 + } 332.1021 + 332.1022 + h3 { 332.1023 + font: @usertext-font; 332.1024 + font-size: 125%; 332.1025 + } 332.1026 + 332.1027 + h4 { 332.1028 + font: @usertext-bold-font; 332.1029 + } 332.1030 + 332.1031 + hr { 332.1032 + border: none; 332.1033 + border-top: 1px solid @main-color; 332.1034 + } 332.1035 + 332.1036 + b, strong { 332.1037 + font: @usertext-italic-font; 332.1038 + } 332.1039 + 332.1040 + i, em { 332.1041 + //font-style: italic; 332.1042 + font: @usertext-bold-font; 332.1043 + } 332.1044 + } 332.1045 + 332.1046 + form, .form { 332.1047 + margin: 0; 332.1048 + padding: 0; 332.1049 + 332.1050 + .ui_field_label { 332.1051 + display: inline-block; 332.1052 + width: 25%; 332.1053 + margin: 0; 332.1054 + padding: 0; 332.1055 + text-align: right; 332.1056 + margin-bottom: @pad; 332.1057 + padding-right: 0.5%; 332.1058 + vertical-align: top; 332.1059 + color: @main-second-color; 332.1060 + } 332.1061 + 332.1062 + input[type=text], 332.1063 + input[type=password], 332.1064 + select, 332.1065 + textarea { 332.1066 + vertical-align: top; 332.1067 + width: 73%; 332.1068 + margin: 0; 332.1069 + padding: 3px; 332.1070 + border: 1px solid @main-second-color; 332.1071 + font: @head3-font; 332.1072 + margin-bottom: @pad; 332.1073 + } 332.1074 + 332.1075 + input:focus { 332.1076 + outline: 2px solid @body-bg-color; 332.1077 + } 332.1078 + 332.1079 + 332.1080 + 332.1081 + .actions { 332.1082 + margin-left: 26%; 332.1083 + } 332.1084 + 332.1085 + } 332.1086 + 332.1087 + form.wide { 332.1088 + input[type=text], 332.1089 + input[type=password], 332.1090 + select, 332.1091 + textarea { 332.1092 + width: 100%; 332.1093 + } 332.1094 + 332.1095 + } 332.1096 + 332.1097 +} 332.1098 + 332.1099 +.issues, .events { 332.1100 + 332.1101 + .event { 332.1102 + 332.1103 + .initiative_pie { 332.1104 + clear: right; 332.1105 + float: right; 332.1106 + } 332.1107 + 332.1108 + ul.initiatives { 332.1109 + 332.1110 + .initiative_info_left { 332.1111 + display: inline; 332.1112 + margin-right: 0.5em; 332.1113 + } 332.1114 + 332.1115 + .initiative_info_right { 332.1116 + float: right; 332.1117 + 332.1118 + .bargraph { 332.1119 + float: right; 332.1120 + margin-left: 0.5em; 332.1121 + } 332.1122 + } 332.1123 + 332.1124 + .result { 332.1125 + color: @main-second-color; 332.1126 + margin-top: 0.5ex; 332.1127 + } 332.1128 + 332.1129 + h3 { 332.1130 + margin-top: 1ex; 332.1131 + margin-bottom: 0; 332.1132 + } 332.1133 + 332.1134 + a.initiative { 332.1135 + font: @head3-font; 332.1136 + } 332.1137 + } 332.1138 + 332.1139 + .event_info { 332.1140 + font: @event-font; 332.1141 + color: @main-event-color; 332.1142 + margin-top: 0.66ex; 332.1143 + margin-bottom: 1ex; 332.1144 + } 332.1145 + 332.1146 + .event_info:last-child { 332.1147 + margin-bottom: 0; 332.1148 + } 332.1149 + 332.1150 + .event_info.negative { 332.1151 + color: @main-negative-event-color; 332.1152 + } 332.1153 + 332.1154 + .event_time { 332.1155 + font: @main-font; 332.1156 + color: @main-second-color; 332.1157 + } 332.1158 + } 332.1159 + 332.1160 + .event:hover { 332.1161 + .event_time { 332.1162 + visibility: visible; 332.1163 + } 332.1164 + ul.initiatives { 332.1165 + div { 332.1166 + visibility: visible; 332.1167 + } 332.1168 + } 332.1169 + } 332.1170 + .issue_context { 332.1171 + line-height: 24px; 332.1172 + margin-bottom: 0.66ex; 332.1173 + .unit { 332.1174 + background-color: #777; 332.1175 + color: #fff; 332.1176 + padding: 1px 3px; 332.1177 + border-radius: @border-radius; 332.1178 + text-decoration: none; 332.1179 + } 332.1180 + .area { 332.1181 + background-color: #ddd; 332.1182 + color: #000; 332.1183 + padding: 1px 3px; 332.1184 + border-radius: @border-radius; 332.1185 + text-decoration: none; 332.1186 + } 332.1187 + } 332.1188 + .issue_info { 332.1189 + .issue { 332.1190 + font: @head3-font; 332.1191 + color: @main-color; 332.1192 + } 332.1193 + } 332.1194 + img.star { 332.1195 + vertical-align: middle; 332.1196 + float: right; 332.1197 + margin-left: 0.5em; 332.1198 + } 332.1199 + 332.1200 + .draft_preview { 332.1201 + } 332.1202 + 332.1203 + .event.suggestion { 332.1204 + 332.1205 + ul.initiatives li { 332.1206 + 332.1207 + margin-top: 0; 332.1208 + margin-bottom: 1ex; 332.1209 + 332.1210 + a { 332.1211 + 332.1212 + font: @main-font; 332.1213 + } 332.1214 + 332.1215 + } 332.1216 + 332.1217 + .suggestion { 332.1218 + 332.1219 + font: @head3-font; 332.1220 + overflow: hidden; 332.1221 + text-overflow: ellipsis; 332.1222 + } 332.1223 + 332.1224 + } 332.1225 + 332.1226 +} 332.1227 + 332.1228 +.suggestions { 332.1229 + 332.1230 + .suggestion { 332.1231 + 332.1232 + .opinion { 332.1233 + float: right; 332.1234 + 332.1235 + .must { 332.1236 + background-color: @must-bg-color; 332.1237 + color: @must-color 332.1238 + } 332.1239 + .should { 332.1240 + background-color: @should-bg-color; 332.1241 + color: @should-color 332.1242 + } 332.1243 + .shouldnot { 332.1244 + background-color: @shouldnot-bg-color; 332.1245 + color: @shouldnot-color 332.1246 + } 332.1247 + .mustnot { 332.1248 + background-color: @mustnot-bg-color; 332.1249 + color: @mustnot-color 332.1250 + } 332.1251 + .implemented { 332.1252 + background-color: @implemented-bg-color; 332.1253 + color: @implemented-color 332.1254 + } 332.1255 + .notimplemented { 332.1256 + background-color: @notimplemented-bg-color; 332.1257 + color: @notimplemented-color 332.1258 + } 332.1259 + 332.1260 + } 332.1261 + 332.1262 + .suggestion-rating { 332.1263 + float: right; 332.1264 + } 332.1265 + .suggestion-text { 332.1266 + margin-top: @pad; 332.1267 + font: @usertext-font; 332.1268 + overflow: hidden; 332.1269 + text-overflow: ellipsis; 332.1270 + position: relative; 332.1271 + z-index: 10; 332.1272 + } 332.1273 + 332.1274 + .suggestion-more { 332.1275 + display: none; 332.1276 + } 332.1277 + 332.1278 + .suggestion-less { 332.1279 + display: none; 332.1280 + } 332.1281 + 332.1282 + .suggestionHead { 332.1283 + overflow: hidden; 332.1284 + text-overflow: ellipsis; 332.1285 + } 332.1286 + 332.1287 + .rating { 332.1288 + display: none; 332.1289 + padding: @pad/2 0; 332.1290 + .active-plus2 { 332.1291 + background-color: @must-bg-color;; 332.1292 + color: @must-color;; 332.1293 + } 332.1294 + .active-plus1 { 332.1295 + background-color: @should-bg-color; 332.1296 + color: @should-color; 332.1297 + } 332.1298 + .active-minus1 { 332.1299 + background-color: @shouldnot-bg-color; 332.1300 + color: @shouldnot-color; 332.1301 + } 332.1302 + .active-minus2 { 332.1303 + background-color: @mustnot-bg-color; 332.1304 + color: @mustnot-color; 332.1305 + } 332.1306 + .active-notfulfilled { 332.1307 + background-color: #faa; 332.1308 + } 332.1309 + .active-fulfilled { 332.1310 + background-color: #afa; 332.1311 + } 332.1312 + } 332.1313 + } 332.1314 + 332.1315 + .suggestion.rateable { 332.1316 + .suggestion-more { 332.1317 + display: block; 332.1318 + } 332.1319 + } 332.1320 + 332.1321 + .suggestion.rateable.unfolded { 332.1322 + .rating { 332.1323 + border-top: 3px solid @body-bg-color; 332.1324 + } 332.1325 + } 332.1326 + 332.1327 + .suggestion.folded { 332.1328 + .suggestion-more { 332.1329 + display: block; 332.1330 + position: absolute; 332.1331 + bottom: 0; 332.1332 + left: 0; 332.1333 + width: 100%; 332.1334 + box-shadow: inset 0 -12ex 10ex -5ex #fff; 332.1335 + padding-top: 5ex; 332.1336 + } 332.1337 + } 332.1338 + 332.1339 + .suggestion.unfolded { 332.1340 + .suggestion-more { 332.1341 + display: none; 332.1342 + } 332.1343 + .rating { 332.1344 + display: block; 332.1345 + } 332.1346 + .suggestion-less { 332.1347 + margin-top: 1ex; 332.1348 + display: block; 332.1349 + } 332.1350 + } 332.1351 + 332.1352 + .suggestion.highlighted { 332.1353 + background-color: @main-highlight-bg-color; 332.1354 + 332.1355 + .suggestion-more { 332.1356 + box-shadow: inset 0 -12ex 10ex -5ex @main-highlight-bg-color; 332.1357 + } 332.1358 + 332.1359 + } 332.1360 + 332.1361 +} 332.1362 + 332.1363 +li.raw { 332.1364 + list-style: none; 332.1365 + padding: 0; 332.1366 + margin: 0 !important; 332.1367 +} 332.1368 + 332.1369 + 332.1370 +.satisfiedSupporterCount { 332.1371 + color: #070; 332.1372 +} 332.1373 +.potentialSupporterCount { 332.1374 + color: #960; 332.1375 +} 332.1376 + 332.1377 +.bargraph { 332.1378 + display: inline-block; 332.1379 + vertical-align: top; 332.1380 + height: 9px; 332.1381 + 332.1382 + div { 332.1383 + margin: 0; 332.1384 + padding: 0; 332.1385 + display: inline-block; 332.1386 + height: 9px; 332.1387 + } 332.1388 + 332.1389 +} 332.1390 + 332.1391 +.diff { 332.1392 + .diff_added { 332.1393 + background-color: #cfc; 332.1394 + } 332.1395 + 332.1396 + .diff_removed { 332.1397 + text-decoration: line-through; 332.1398 + background-color: #fcc; 332.1399 + } 332.1400 +} 332.1401 + 332.1402 +.btn, .ui_paginate_foot a { 332.1403 + text-decoration: none; 332.1404 + min-width: 2em; 332.1405 + text-align: center; 332.1406 + display: inline-block; 332.1407 + border-radius: @btn-border-radius; 332.1408 + border: none; 332.1409 + font: @btn-font; 332.1410 + background-color: #999; 332.1411 + color: #fff !important; 332.1412 + margin-bottom: 5px; 332.1413 +} 332.1414 + 332.1415 +.btn { 332.1416 + padding: 1ex 1em; 332.1417 +} 332.1418 + 332.1419 + 332.1420 + 332.1421 +.ui_paginate_foot a { 332.1422 + padding: 0.5ex 0.5em; 332.1423 + background-color: #eee; 332.1424 + color: 000 !important; 332.1425 +} 332.1426 + 332.1427 +.ui_paginate_foot a.active { 332.1428 + background-color: #666; 332.1429 + color: #fff !important; 332.1430 +} 332.1431 + 332.1432 +.btn-default { 332.1433 + background-color: #47a; 332.1434 + color: #fff !important; 332.1435 +} 332.1436 + 332.1437 +.btn:hover, .btn:focus, .ui_paginate_foot a:hover, .ui_paginate_foot a:focus { 332.1438 + background-color: #0a0; 332.1439 + color: #fff !important; 332.1440 + cursor: pointer; 332.1441 +} 332.1442 + 332.1443 +.btn-dangerous:hover { 332.1444 + background-color: #c00; 332.1445 + color: #fff !important; 332.1446 +} 332.1447 + 332.1448 +.btn-link { 332.1449 + font: @main-font; 332.1450 + background-color: @main-bg-color; 332.1451 + color: @main-link-color; 332.1452 + border: none; 332.1453 + padding: 0; 332.1454 + margin: 0; 332.1455 + text-decoration: underline; 332.1456 + cursor: pointer; 332.1457 +} 332.1458 + 332.1459 +/************************************************************************* 332.1460 + * Voting 332.1461 + */ 332.1462 + 332.1463 +.main .section #voting_form .sectionRow:last-child { 332.1464 + border-radius: 0; 332.1465 + margin-bottom: 0; 332.1466 +} 332.1467 + 332.1468 +#voting { 332.1469 + background: #ddd; 332.1470 + padding: @pad; 332.1471 + margin-top: 4px; 332.1472 + position: relative; 332.1473 + margin-bottom: 2ex; 332.1474 + 332.1475 + .approval, 332.1476 + .abstention, 332.1477 + .disapproval { 332.1478 + border: 2px black solid; 332.1479 + margin-bottom: 2ex; 332.1480 + padding: 1ex; 332.1481 + padding-bottom: 2ex; 332.1482 + border-radius: @border-radius; 332.1483 + } 332.1484 + 332.1485 + .disapproval { 332.1486 + margin-bottom: 2ex; 332.1487 + } 332.1488 + 332.1489 + .approval { 332.1490 + background-color: #9f9; 332.1491 + 332.1492 + .movable { 332.1493 + background-color: #dfd; 332.1494 + } 332.1495 + } 332.1496 + 332.1497 + .abstention { 332.1498 + background-color: #ccc; 332.1499 + 332.1500 + .movable { 332.1501 + background-color: #f2f2f2; 332.1502 + } 332.1503 + } 332.1504 + 332.1505 + .disapproval { 332.1506 + background-color: #f88; 332.1507 + 332.1508 + .movable { 332.1509 + background-color: #fbb; 332.1510 + } 332.1511 + } 332.1512 + 332.1513 + .movable { 332.1514 + position: relative; 332.1515 + border: 1px black solid; 332.1516 + margin-top: 1ex; 332.1517 + padding: 0.5ex; 332.1518 + border-radius: @border-radius; 332.1519 + } 332.1520 + 332.1521 + .voting_form_active { 332.1522 + .movable { 332.1523 + cursor: pointer; 332.1524 + vertical-align: middle; 332.1525 + cursor: move; 332.1526 + } 332.1527 + 332.1528 + .clickable { 332.1529 + cursor: auto; 332.1530 + } 332.1531 + 332.1532 + a.clickable { 332.1533 + cursor: pointer; 332.1534 + } 332.1535 + } 332.1536 +} 332.1537 + 332.1538 + 332.1539 +/* 332.1540 + * footer 332.1541 + */ 332.1542 + 332.1543 +.footer { 332.1544 + text-align: center; 332.1545 + color: @footer-color; 332.1546 + background-color: @footer-bg-color; 332.1547 + padding: @pad 0; 332.1548 + border: 1px solid #000; 332.1549 + border-top: none; 332.1550 + 332.1551 + a { 332.1552 + color: @body-color; 332.1553 + } 332.1554 +} 332.1555 + 332.1556 + 332.1557 +.ui_paginate_head { 332.1558 + display: none; 332.1559 +} 332.1560 + 332.1561 +.ui_paginate_foot { 332.1562 + line-height: 180%; 332.1563 +} 332.1564 + 332.1565 + 332.1566 +.swiper_tabs { 332.1567 + display: none; 332.1568 +} 332.1569 + 332.1570 +#swiper_info { 332.1571 + display: none; 332.1572 +} 332.1573 + 332.1574 +.nav .searchLink { 332.1575 + display: none; 332.1576 +} 332.1577 + 332.1578 + 332.1579 +@media (max-width: 767px) { 332.1580 + 332.1581 +html { 332.1582 + 332.1583 + body { 332.1584 + margin: 0; 332.1585 + background: @mobile-bg-color; 332.1586 + 332.1587 + .head { 332.1588 + margin: @grid/2; 332.1589 + padding: 0; 332.1590 + 332.1591 + .logo { 332.1592 + display: block; 332.1593 + padding: 0; 332.1594 + 332.1595 + .liquid, .feedback { 332.1596 + font: @mobile-logo-font; 332.1597 + } 332.1598 + 332.1599 + .instanceName { 332.1600 + font: @mobile-instance-font; 332.1601 + display: block; 332.1602 + margin-left: 0; 332.1603 + } 332.1604 + } 332.1605 + .nav { 332.1606 + padding: 0; 332.1607 + } 332.1608 + } 332.1609 + 332.1610 + .initiativeInfo h1 { 332.1611 + display: none; 332.1612 + } 332.1613 + 332.1614 + .slot_title { 332.1615 + 332.1616 + font: @head2-font; 332.1617 + padding: 0; 332.1618 + margin: 0 @grid/2; 332.1619 + 332.1620 + .spacer { 332.1621 + display: none; 332.1622 + } 332.1623 + 332.1624 + .unit, .area, .issue, .initiative, .member { 332.1625 + display: block; 332.1626 + margin-right: 0; 332.1627 + padding: 4px 0; 332.1628 + border-radius: @border-radius; 332.1629 + overflow: auto; 332.1630 + } 332.1631 + 332.1632 + .unit:before, .area:before, .issue:before, .initiative:before, .member:before { 332.1633 + content: "↳"; 332.1634 + position: relative; 332.1635 + top: -2px; 332.1636 + } 332.1637 + 332.1638 + .area { 332.1639 + margin-left: 10px; 332.1640 + } 332.1641 + .issue { 332.1642 + margin-left: 10px * 2; 332.1643 + } 332.1644 + .initiative { 332.1645 + margin-left: 10px * 3; 332.1646 + } 332.1647 + 332.1648 + a:last-child, .issue:last-child, .area:last-child, .unit:last-child, .initiative:last-child { 332.1649 + margin-bottom: @grid/2; 332.1650 + } 332.1651 + 332.1652 + .unit, .initiative, .issue, .area { 332.1653 + a { 332.1654 + margin-bottom: 0; 332.1655 + display: inline; 332.1656 + } 332.1657 + } 332.1658 + 332.1659 + a.home { 332.1660 + display: none; 332.1661 + } 332.1662 + 332.1663 + .weight { 332.1664 + float: right; 332.1665 + margin: 0; 332.1666 + } 332.1667 + 332.1668 + .delegation_info { 332.1669 + float: right; 332.1670 + display: block; 332.1671 + margin-top: -10px; 332.1672 + } 332.1673 + a .label { 332.1674 + display: inline; 332.1675 + } 332.1676 + .star { 332.1677 + float: right; 332.1678 + margin-left: 0.5em; 332.1679 + margin-top: -@pad/2; 332.1680 + margin-bottom: -@pad/2; 332.1681 + } 332.1682 + } 332.1683 + 332.1684 + .slot_title > span > *:last-child { 332.1685 + font: @head1-font; 332.1686 + } 332.1687 + 332.1688 + 332.1689 + .page { 332.1690 + background: none; 332.1691 + margin: 0; 332.1692 + box-shadow: none; 332.1693 + } 332.1694 + 332.1695 + .nav #member_menu .text { 332.1696 + display: none; 332.1697 + } 332.1698 + 332.1699 + .nav form.search { 332.1700 + display: none; 332.1701 + } 332.1702 + 332.1703 + .nav .notifications, 332.1704 + .nav .searchLink, 332.1705 + .nav #member_menu a { 332.1706 + vertical-align: middle; 332.1707 + display: inline-block; 332.1708 + height: 48px; 332.1709 + min-width: 35px; 332.1710 + text-align: center; 332.1711 + background-color: #000; 332.1712 + border: 1px solid #777; 332.1713 + border-radius: @border-radius; 332.1714 + img { 332.1715 + margin: 0; 332.1716 + width: 48px; 332.1717 + height: 48px; 332.1718 + } 332.1719 + margin: 0; 332.1720 + } 332.1721 + 332.1722 + .nav .notifications { 332.1723 + padding: 12px 2px; 332.1724 + height: 24px; 332.1725 + } 332.1726 + 332.1727 + .nav #member_menu a :last-child { 332.1728 + display: none; 332.1729 + } 332.1730 + 332.1731 + .notifications span { 332.1732 + margin-left: -5px; 332.1733 + } 332.1734 + 332.1735 + .swiper_tabs { 332.1736 + clear: both; 332.1737 + display: block; 332.1738 + overflow: auto; 332.1739 + margin: @grid/2; 332.1740 + 332.1741 + div { 332.1742 + display: block; 332.1743 + float: left; 332.1744 + width: 33.333%; 332.1745 + 332.1746 + a { 332.1747 + padding: 8px 0; 332.1748 + display: block; 332.1749 + text-align: center; 332.1750 + background-color: #eee; 332.1751 + } 332.1752 + 332.1753 + a.active { 332.1754 + background-color: #abe; 332.1755 + } 332.1756 + } 332.1757 + div:first-child a { 332.1758 + border-radius: @border-radius 0 0 @border-radius; 332.1759 + } 332.1760 + 332.1761 + div:last-child a { 332.1762 + border-radius: 0 @border-radius @border-radius 0; 332.1763 + } 332.1764 + } 332.1765 + 332.1766 + #swiper_info.active { 332.1767 + display: block; 332.1768 + font: @head3-font; 332.1769 + z-index: 1; 332.1770 + text-align: center; 332.1771 + width: 100%; 332.1772 + background-color: @mobile-bg-color; 332.1773 + color: @body-color; 332.1774 + } 332.1775 + 332.1776 + .sidebarSection { 332.1777 + margin: 0 @grid/2 @grid/2 @grid/2; 332.1778 + } 332.1779 + 332.1780 + .main, .extra > .section { 332.1781 + clear: none; 332.1782 + float: none; 332.1783 + width: auto; 332.1784 + margin: 0 @grid/2 @grid/2 @grid/2; 332.1785 + .section .sectionRow:last-child { 332.1786 + margin-bottom: @grid/2; 332.1787 + } 332.1788 + 332.1789 + } 332.1790 + 332.1791 + .ui_filter_head.filter_mode { 332.1792 + float: none !important; 332.1793 + background: @main-bg-color !important; 332.1794 + text-align: left !important; 332.1795 + border-radius: @border-radius; 332.1796 + margin-bottom: @grid/2 !important; 332.1797 + } 332.1798 + 332.1799 + .member_photo { 332.1800 + text-align: center; 332.1801 + margin-bottom: 2ex; 332.1802 + .member_image_photo { 332.1803 + max-width: 600px; 332.1804 + } 332.1805 + } 332.1806 + 332.1807 + #trace_content { 332.1808 + margin: @grid/2 0; 332.1809 + border-radius: 0; 332.1810 + 332.1811 + ul { 332.1812 + li { 332.1813 + .trace_head { 332.1814 + padding: 6px 5px; 332.1815 + } 332.1816 + } 332.1817 + ul { 332.1818 + padding: 5px 2px; 332.1819 + } 332.1820 + } 332.1821 + } 332.1822 + 332.1823 + } 332.1824 +} } 332.1825 + 332.1826 +.textCenter { 332.1827 + text-align: center; 332.1828 +} 332.1829 + 332.1830 +a.initiative { 332.1831 + text-decoration: none; 332.1832 + border-bottom: 1px solid #66c; 332.1833 +} 332.1834 + 332.1835 +a.initiative:hover { 332.1836 + border-bottom: 1px solid #007; 332.1837 +} 332.1838 + 332.1839 + 332.1840 + 332.1841 +#trace_content { 332.1842 + margin: @grid; 332.1843 + padding: @pad; 332.1844 + border-radius: @border-radius; 332.1845 + background-color: @main-bg-color; 332.1846 + 332.1847 + #system_error { 332.1848 + font-family: monospace; 332.1849 + } 332.1850 + 332.1851 + ul { 332.1852 + li { 332.1853 + margin-top: 10px; 332.1854 + .trace_head { 332.1855 + padding: 3px 5px; 332.1856 + border-radius: @border-radius @border-radius 0 0; 332.1857 + } 332.1858 + .trace_head:last-child { 332.1859 + border-radius: @border-radius; 332.1860 + } 332.1861 + ul { 332.1862 + border-radius: 0 0 @border-radius @border-radius; 332.1863 + } 332.1864 + } 332.1865 + li:first-child { 332.1866 + margin-top: 0; 332.1867 + } 332.1868 + ul { 332.1869 + padding: 10px; 332.1870 + } 332.1871 + } 332.1872 + 332.1873 + .trace_config > ul { 332.1874 + background-color: #eee; 332.1875 + border: 1px solid #ccc; 332.1876 + } 332.1877 + .trace_config > .trace_head { 332.1878 + background-color: #ccc; 332.1879 + color: #000; 332.1880 + } 332.1881 + .trace_request > ul { 332.1882 + background-color: #afa; 332.1883 + } 332.1884 + .trace_request > .trace_head { 332.1885 + background-color: #0c0; 332.1886 + } 332.1887 + .trace_filter > ul { 332.1888 + background-color: #ccf; 332.1889 + border: 1px solid #00c; 332.1890 + border-top: none; 332.1891 + } 332.1892 + .trace_filter > .trace_head { 332.1893 + background-color: #00c; 332.1894 + color: #fff; 332.1895 + } 332.1896 + .trace_view > ul { 332.1897 + background-color: #cfc; 332.1898 + border: 1px solid #0c0; 332.1899 + border-top: none; 332.1900 + } 332.1901 + .trace_view > .trace_head { 332.1902 + background-color: #0c0; 332.1903 + color: #000; 332.1904 + } 332.1905 + .trace_action_neutral > ul { 332.1906 + background-color: #ffa; 332.1907 + border: 1px solid #fe0; 332.1908 + } 332.1909 + .trace_action_neutral > .trace_head { 332.1910 + background-color: #fe0; 332.1911 + color: #000; 332.1912 + } 332.1913 + .trace_sql { 332.1914 + background-color: #fff; 332.1915 + padding: 2px 4px; 332.1916 + margin-top: 8px; 332.1917 + } 332.1918 + .trace_error { 332.1919 + background-color: #faa; 332.1920 + color: #000; 332.1921 + font-weight: bold; 332.1922 + border: 1px solid #c00; 332.1923 + } 332.1924 + .trace_exectime { 332.1925 + background-color: #ccc; 332.1926 + font-weight: bold; 332.1927 + border-radius: @border-radius; 332.1928 + } 332.1929 + 332.1930 + .time { 332.1931 + float: right; 332.1932 + } 332.1933 + 332.1934 + .total_duration { 332.1935 + font-weight: bold; 332.1936 + } 332.1937 + 332.1938 +} 332.1939 \ No newline at end of file
333.1 Binary file static/star.png has changed
334.1 --- a/static/style.css Thu Jul 10 01:02:43 2014 +0200 334.2 +++ b/static/style.css Thu Jul 10 01:19:48 2014 +0200 334.3 @@ -139,6 +139,10 @@ 334.4 border-radius: 4px; 334.5 } 334.6 334.7 +.btn-default { 334.8 + 334.9 +} 334.10 + 334.11 /************************************************************************* 334.12 * Notices, warnings and errors 334.13 */ 334.14 @@ -816,6 +820,11 @@ 334.15 margin-bottom: 0; 334.16 } 334.17 334.18 +.vertical .actions { 334.19 + margin-left: 33%; 334.20 +} 334.21 + 334.22 + 334.23 #voting_form input[type=submit], 334.24 .login input[type=submit], 334.25 .vertical input[type=submit] {
335.1 --- a/utils/optparse.lua Thu Jul 10 01:02:43 2014 +0200 335.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 335.3 @@ -1,139 +0,0 @@ 335.4 --- Lua command line option parser. 335.5 --- Interface based on Pythons optparse. 335.6 --- http://docs.python.org/lib/module-optparse.html 335.7 --- (c) 2008 David Manura, Licensed under the same terms as Lua (MIT license) 335.8 --- 335.9 --- To be used like this: 335.10 --- t={usage="<some usage message>", version="<version string>"} 335.11 --- op=OptionParser(t) 335.12 --- op=add_option{"<opt>", action=<action>, dest=<dest>, help="<help message for this option>"} 335.13 --- 335.14 --- with : 335.15 --- <opt> the option string to be used (can be anything, if one letter opt, then should be -x val, more letters: -xy=val ) 335.16 --- <action> one of 335.17 --- - store: store in options as key, val 335.18 --- - store_true: stores key, true 335.19 --- - store_false: stores key, false 335.20 --- <dest> is the key under which the option is saved 335.21 --- 335.22 --- options,args = op.parse_args() 335.23 --- 335.24 --- now options is the table of options (key, val) and args is the table with non-option arguments. 335.25 --- You can use op.fail(message) for failing and op.print_help() for printing the usage as you like. 335.26 - 335.27 ---module('utils.optparse') 335.28 - 335.29 -local function OptionParser(t) 335.30 - local usage = t.usage 335.31 - local version = t.version 335.32 - local commands = t.commands 335.33 - 335.34 - local o = {} 335.35 - local option_descriptions = {} 335.36 - local option_of = {} 335.37 - 335.38 - function o.fail(s) -- extension 335.39 - io.stderr:write(s .. '\n') 335.40 - os.exit(1) 335.41 - end 335.42 - 335.43 - function o.add_option(optdesc) 335.44 - option_descriptions[#option_descriptions+1] = optdesc 335.45 - for _,v in pairs(optdesc) do 335.46 - option_of[v] = optdesc 335.47 - end 335.48 - end 335.49 - function o.parse_args() 335.50 - -- expand options (e.g. "--input=file" -> "--input", "file") 335.51 - local arg = {unpack(arg)} 335.52 - for i=#arg,1,-1 do local v = arg[i] 335.53 - local flag, val = v:match('^(%-%-%w+)=(.*)') 335.54 - if flag then 335.55 - arg[i] = flag 335.56 - table.insert(arg, i+1, val) 335.57 - end 335.58 - end 335.59 - 335.60 - local options = {} 335.61 - for _,optdesc in ipairs(option_descriptions) do 335.62 - options[optdesc["dest"]] = optdesc.default 335.63 - end 335.64 - local args = {} 335.65 - local i = 1 335.66 - while i <= #arg do local v = arg[i] 335.67 - local optdesc = option_of[v] 335.68 - if optdesc then 335.69 - local action = optdesc.action 335.70 - local val 335.71 - if action == 'store' or action == nil then 335.72 - i = i + 1 335.73 - val = arg[i] 335.74 - if not val then o.fail('option requires an argument ' .. v) end 335.75 - elseif action == 'store_true' then 335.76 - val = true 335.77 - elseif action == 'store_false' then 335.78 - val = false 335.79 - end 335.80 - options[optdesc.dest] = val 335.81 - else 335.82 - if v:match('^%-') then o.fail('invalid option ' .. v) end 335.83 - args[#args+1] = v 335.84 - end 335.85 - i = i + 1 335.86 - end 335.87 - if options.help then 335.88 - o.print_help() 335.89 - os.exit() 335.90 - end 335.91 - if options.version then 335.92 - io.stdout:write(t.version .. "\n") 335.93 - os.exit() 335.94 - end 335.95 - return options, args 335.96 - end 335.97 - 335.98 - local function flags_str(optdesc) 335.99 - local sflags = {} 335.100 - local action = optdesc.action 335.101 - for _,flag in ipairs(optdesc) do 335.102 - local sflagend 335.103 - if action == nil or action == 'store' then 335.104 - local metavar = optdesc.metavar or optdesc.dest:upper() 335.105 - sflagend = #flag == 2 and ' ' .. metavar 335.106 - or '=' .. metavar 335.107 - else 335.108 - sflagend = '' 335.109 - end 335.110 - sflags[#sflags+1] = flag .. sflagend 335.111 - end 335.112 - return table.concat(sflags, ', ') 335.113 - end 335.114 - 335.115 - function o.print_help() 335.116 - io.stdout:write("Usage: " .. usage:gsub('%%prog', arg[0]) .. "\n") 335.117 - io.stdout:write("\n") 335.118 - io.stdout:write("Options:\n") 335.119 - for _,optdesc in ipairs(option_descriptions) do 335.120 - io.stdout:write(" " .. flags_str(optdesc) .. 335.121 - " " .. optdesc.help .. "\n") 335.122 - end 335.123 - if commands then 335.124 - io.stdout:write("\nCommands:\n") 335.125 - for _,command in ipairs(commands) do 335.126 - io.stdout:write(" " .. command[1] .. 335.127 - string.rep(" ", 30-#command[1]) .. 335.128 - command[2] .. "\n") 335.129 - end 335.130 - end 335.131 - 335.132 - end 335.133 - o.add_option{"--help", action="store_true", dest="help", 335.134 - help="show this help message and exit"} 335.135 - if t.version then 335.136 - o.add_option{"--version", action="store_true", dest="version", 335.137 - help="output version info."} 335.138 - end 335.139 - return o 335.140 -end 335.141 - 335.142 -return OptionParser 335.143 \ No newline at end of file