Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/polls.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>2016-02-20 19:15:07 +0300
committerVinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>2016-02-20 19:15:07 +0300
commitc3f94802f28f8b44335eb9d3067c6dc0de9f51e0 (patch)
tree95d52bcb317ad3ad1a673ae77719d8d4ad1984d4
parent28fa26961991fa01736fcb8d226c3203f6b5a6a5 (diff)
initial commit0.6.0
-rw-r--r--.gitignore1
-rw-r--r--README.md9
-rw-r--r--appinfo/app.php34
-rw-r--r--appinfo/application.php112
-rwxr-xr-xappinfo/database.xml222
-rwxr-xr-xappinfo/info.xml16
-rw-r--r--appinfo/routes.php32
-rw-r--r--controller/pagecontroller.php410
-rw-r--r--css/jquery.datetimepicker.css568
-rw-r--r--css/main.css409
-rw-r--r--db/access.php15
-rw-r--r--db/accessmapper.php49
-rw-r--r--db/comment.php21
-rw-r--r--db/commentmapper.php79
-rw-r--r--db/date.php15
-rw-r--r--db/datemapper.php68
-rw-r--r--db/event.php33
-rw-r--r--db/eventmapper.php101
-rw-r--r--db/notification.php15
-rw-r--r--db/notificationmapper.php68
-rw-r--r--db/participation.php21
-rw-r--r--db/participationmapper.php84
-rw-r--r--db/text.php15
-rw-r--r--db/textmapper.php53
-rw-r--r--img/app-logo-polls.svg83
-rw-r--r--index.php14
-rw-r--r--js/create_edit.js460
-rw-r--r--js/jquery.datetimepicker.full.min.js2
-rw-r--r--js/last.js166
-rwxr-xr-xjs/start.js57
-rw-r--r--js/vote.js156
-rw-r--r--l10n/ca.json72
-rw-r--r--l10n/ca.php73
-rw-r--r--l10n/de.json83
-rw-r--r--l10n/de.php84
-rw-r--r--l10n/de_DE.json83
-rw-r--r--l10n/en.json81
-rw-r--r--l10n/en.php82
-rw-r--r--l10n/es.json72
-rw-r--r--l10n/es.php73
-rw-r--r--l10n/fr.json72
-rw-r--r--l10n/fr.php73
-rw-r--r--templates/create.tmpl.php161
-rw-r--r--templates/goto.tmpl.php382
-rw-r--r--templates/main.tmpl.php142
-rw-r--r--templates/no.acc.tmpl.php13
46 files changed, 4933 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..d8fe4fa7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.project
diff --git a/README.md b/README.md
index 5d73b0f6..00b2899b 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,8 @@
-# polls \ No newline at end of file
+polls
+=====
+
+polls for ownCloud
+
+Put the files under <owncloud_dir>/apps/polls and enable it in ownCloud.
+
+The app is also available at the [appstore](https://apps.owncloud.com/content/show.php/Polls?content=167919).
diff --git a/appinfo/app.php b/appinfo/app.php
new file mode 100644
index 00000000..113fc033
--- /dev/null
+++ b/appinfo/app.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * ownCloud - polls
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
+ * @copyright Vinzenz Rosenkranz 2016
+ */
+
+namespace OCA\Polls\AppInfo;
+
+$l = \OC::$server->getL10N('polls');
+
+\OC::$server->getNavigationManager()->add(array(
+ // the string under which your app will be referenced in owncloud
+ 'id' => 'polls',
+
+ // sorting weight for the navigation. The higher the number, the higher
+ // will it be listed in the navigation
+ 'order' => 77,
+
+ // the route that will be shown on startup
+ 'href' => \OC::$server->getURLGenerator()->linkToRoute('polls.page.index'),
+
+ // the icon that will be shown in the navigation
+ // this file needs to exist in img/
+ 'icon' => \OC::$server->getURLGenerator()->imagePath('polls', 'app-logo-polls.svg'),
+
+ // the title of your application. This will be used in the
+ // navigation or on the settings page of your app
+ 'name' => $l->t('Polls')
+));
diff --git a/appinfo/application.php b/appinfo/application.php
new file mode 100644
index 00000000..df167c0b
--- /dev/null
+++ b/appinfo/application.php
@@ -0,0 +1,112 @@
+<?php
+/**
+ * ownCloud - polls
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
+ * @copyright Vinzenz Rosenkranz 2016
+ */
+
+namespace OCA\Polls\AppInfo;
+
+
+use OC\AppFramework\Utility\SimpleContainer;
+use \OCP\AppFramework\App;
+use \OCA\Polls\Db\AccessMapper;
+use \OCA\Polls\Db\CommentMapper;
+use \OCA\Polls\Db\DateMapper;
+use \OCA\Polls\Db\EventMapper;
+use \OCA\Polls\Db\NotificationMapper;
+use \OCA\Polls\Db\ParticipationMapper;
+use \OCA\Polls\Db\TextMapper;
+use \OCA\Polls\Controller\PageController;
+
+
+class Application extends App {
+
+
+ public function __construct (array $urlParams=array()) {
+ parent::__construct('polls', $urlParams);
+
+ $container = $this->getContainer();
+
+ /**
+ * Controllers
+ */
+ $container->registerService('PageController', function($c) {
+ /** @var SimpleContainer $c */
+ return new PageController(
+ $c->query('AppName'),
+ $c->query('Request'),
+ $c->query('UserManager'),
+ $c->query('Logger'),
+ $c->query('ServerContainer')->getURLGenerator(),
+ $c->query('UserId'),
+ $c->query('AccessMapper'),
+ $c->query('CommentMapper'),
+ $c->query('DateMapper'),
+ $c->query('EventMapper'),
+ $c->query('NotificationMapper'),
+ $c->query('ParticipationMapper'),
+ $c->query('TextMapper')
+ );
+ });
+
+ $container->registerService('UserManager', function($c) {
+ return $c->query('ServerContainer')->getUserManager();
+ });
+
+ $container->registerService('Logger', function($c) {
+ return $c->query('ServerContainer')->getLogger();
+ });
+
+ $server = $container->getServer();
+ $container->registerService('AccessMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new AccessMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('CommentMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new CommentMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('DateMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new DateMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('EventMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new EventMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('NotificationMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new NotificationMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('ParticipationMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new ParticipationMapper(
+ $server->getDb()
+ );
+ });
+ $container->registerService('TextMapper', function($c) use ($server) {
+ /** @var SimpleContainer $c */
+ return new TextMapper(
+ $server->getDb()
+ );
+ });
+
+ }
+
+
+}
diff --git a/appinfo/database.xml b/appinfo/database.xml
new file mode 100755
index 00000000..86f50702
--- /dev/null
+++ b/appinfo/database.xml
@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<database>
+ <name>*dbname*</name>
+ <create>true</create>
+ <overwrite>false</overwrite>
+ <charset>utf8</charset>
+ <table>
+ <name>*dbprefix*polls_events</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <default>0</default>
+ </field>
+ <field>
+ <name>hash</name>
+ <type>text</type>
+ <length>64</length>
+ </field>
+ <field>
+ <name>type</name>
+ <type>integer</type>
+ <notnull>false</notnull>
+ <length>16</length>
+ </field>
+ <field>
+ <name>title</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>128</length>
+ </field>
+ <field>
+ <name>description</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>1024</length>
+ </field>
+ <field>
+ <name>owner</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ <field>
+ <name>created</name>
+ <type>timestamp</type>
+ </field>
+ <field>
+ <name>access</name>
+ <type>text</type>
+ <notnull>false</notnull>
+ <length>1024</length>
+ </field>
+ <field>
+ <name>expire</name>
+ <type>timestamp</type>
+ </field>
+
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_dts</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>dt</name>
+ <type>timestamp</type>
+ <length>32</length>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_txts</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>text</name>
+ <type>text</type>
+ <length>256</length>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_particip</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>dt</name>
+ <type>timestamp</type>
+ </field>
+ <field>
+ <name>type</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>user_id</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_particip_text</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>text</name>
+ <type>text</type>
+ <length>256</length>
+ </field>
+ <field>
+ <name>user_id</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ <field>
+ <name>type</name>
+ <type>integer</type>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_comments</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ <default>0</default>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>user_id</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ <field>
+ <name>dt</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>32</length>
+ </field>
+ <field>
+ <name>comment</name>
+ <type>text</type>
+ <notnull>false</notnull>
+ <length>1024</length>
+ </field>
+ </declaration>
+ </table>
+ <table>
+ <name>*dbprefix*polls_notif</name>
+ <declaration>
+ <field>
+ <name>id</name>
+ <type>integer</type>
+ <default>0</default>
+ <notnull>true</notnull>
+ <autoincrement>1</autoincrement>
+ </field>
+ <field>
+ <name>poll_id</name>
+ <type>integer</type>
+ </field>
+ <field>
+ <name>user_id</name>
+ <type>text</type>
+ <notnull>true</notnull>
+ <length>64</length>
+ </field>
+ </declaration>
+ </table>
+
+</database>
diff --git a/appinfo/info.xml b/appinfo/info.xml
new file mode 100755
index 00000000..3aad6ace
--- /dev/null
+++ b/appinfo/info.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<info>
+ <id>polls</id>
+ <name>Polls</name>
+ <description>event schedule polls</description>
+ <version>0.6.9</version>
+ <licence>AGPL</licence>
+ <author>Vinzenz Rosenkranz</author>
+ <requiremin>8.1</requiremin>
+ <category>tools</category>
+ <bugs>https://github.com/v1r0x/polls/issues</bugs>
+ <repository type="git">https://github.com/v1r0x/polls.git</repository>
+ <dependencies>
+ <owncloud min-version="8.1" max-version="9"/>
+ </dependencies>
+</info>
diff --git a/appinfo/routes.php b/appinfo/routes.php
new file mode 100644
index 00000000..0d1b873a
--- /dev/null
+++ b/appinfo/routes.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * This file is licensed under the Affero General Public License version 3 or later.
+ * See the COPYING-README file.
+ *
+ * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
+ * @copyright Vinzenz Rosenkranz 2016
+ */
+
+namespace OCA\Polls\AppInfo;
+
+/**
+ * Create your routes in here. The name is the lowercase name of the controller
+ * without the controller part, the stuff after the hash is the method.
+ * e.g. page#index -> PageController->index()
+ *
+ * The controller class has to be registered in the application.php file since
+ * it's instantiated in there
+ */
+$application = new Application();
+
+$application->registerRoutes($this, array('routes' => array(
+ array('name' => 'page#index', 'url' => '/', 'verb' => 'GET'),
+ array('name' => 'page#goto_poll', 'url' => '/goto/{hash}', 'verb' => 'GET'),
+ array('name' => 'page#edit_poll', 'url' => '/edit/{hash}', 'verb' => 'GET'),
+ array('name' => 'page#create_poll', 'url' => '/create', 'verb' => 'GET'),
+ array('name' => 'page#delete_poll', 'url' => '/delete', 'verb' => 'POST'),
+ array('name' => 'page#update_poll', 'url' => '/update', 'verb' => 'POST'),
+ array('name' => 'page#insert_poll', 'url' => '/insert', 'verb' => 'POST'),
+ array('name' => 'page#insert_vote', 'url' => '/insert/vote', 'verb' => 'POST'),
+ array('name' => 'page#insert_comment', 'url' => '/insert/comment', 'verb' => 'POST'),
+)));
diff --git a/controller/pagecontroller.php b/controller/pagecontroller.php
new file mode 100644
index 00000000..45d768e8
--- /dev/null
+++ b/controller/pagecontroller.php
@@ -0,0 +1,410 @@
+<?php
+/**
+ * ownCloud - polls
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later. See the COPYING file.
+ *
+ * @author Vinzenz Rosenkranz <vinzenz.rosenkranz@gmail.com>
+ * @copyright Vinzenz Rosenkranz 2016
+ */
+
+namespace OCA\Polls\Controller;
+
+use \OCA\Polls\Db\Access;
+use \OCA\Polls\Db\Comment;
+use \OCA\Polls\Db\Date;
+use \OCA\Polls\Db\Event;
+use \OCA\Polls\Db\Notification;
+use \OCA\Polls\Db\Participation;
+use \OCA\Polls\Db\Text;
+
+use \OCA\Polls\Db\AccessMapper;
+use \OCA\Polls\Db\CommentMapper;
+use \OCA\Polls\Db\DateMapper;
+use \OCA\Polls\Db\EventMapper;
+use \OCA\Polls\Db\NotificationMapper;
+use \OCA\Polls\Db\ParticipationMapper;
+use \OCA\Polls\Db\TextMapper;
+use \OCP\IUserManager;
+use \OCP\ILogger;
+use \OCP\IRequest;
+use \OCP\IURLGenerator;
+use \OCP\AppFramework\Http\TemplateResponse;
+use \OCP\AppFramework\Http\RedirectResponse;
+use \OCP\AppFramework\Controller;
+
+$userMgr = \OC::$server->getUserManager();
+
+class PageController extends Controller {
+
+ private $userId;
+ private $accessMapper;
+ private $commentMapper;
+ private $dateMapper;
+ private $eventMapper;
+ private $notificationMapper;
+ private $participationMapper;
+ private $textMapper;
+ private $urlGenerator;
+ private $manager;
+ private $logger;
+ public function __construct($appName, IRequest $request,
+ IUserManager $manager,
+ ILogger $logger,
+ IURLGenerator $urlGenerator,
+ $userId,
+ AccessMapper $accessMapper,
+ CommentMapper $commentMapper,
+ DateMapper $dateMapper,
+ EventMapper $eventMapper,
+ NotificationMapper $notificationMapper,
+ ParticipationMapper $ParticipationMapper,
+ TextMapper $textMapper) {
+ parent::__construct($appName, $request);
+ $this->manager = $manager;
+ $this->logger = $logger;
+ $this->urlGenerator = $urlGenerator;
+ $this->userId = $userId;
+ $this->accessMapper = $accessMapper;
+ $this->commentMapper = $commentMapper;
+ $this->dateMapper = $dateMapper;
+ $this->eventMapper = $eventMapper;
+ $this->notificationMapper = $notificationMapper;
+ $this->participationMapper = $ParticipationMapper;
+ $this->textMapper = $textMapper;
+ }
+
+ /**
+ * CAUTION: the @Stuff turn off security checks, for this page no admin is
+ * required and no CSRF check. If you don't know what CSRF is, read
+ * it up in the docs or you might create a security hole. This is
+ * basically the only required method to add this exemption, don't
+ * add it to any other method if you don't exactly know what it does
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function index() {
+ $polls = $this->eventMapper->findAll();
+ $comments = $this->commentMapper->findDistinctByUser($this->userId);
+ $partic = $this->participationMapper->findDistinctByUser($this->userId);
+ $response = new TemplateResponse('polls', 'main.tmpl', ['polls' => $polls, 'comments' => $comments, 'participations' => $partic, 'userId' => $this->userId, 'userMgr' => $this->manager, 'urlGenerator' => $this->urlGenerator]);
+ if (class_exists('OCP\AppFramework\Http\ContentSecurityPolicy')) {
+ $csp = new \OCP\AppFramework\Http\ContentSecurityPolicy();
+ $response->setContentSecurityPolicy($csp);
+ }
+ return $response;
+ }
+
+ private function sendNotifications($pollId, $from) {
+ $poll = $this->eventMapper->find($pollId);
+ $notifs = $this->notificationMapper->findAllByPoll($pollId);
+ foreach($notifs as $notif) {
+ if($from === $notif->getUserId()) continue;
+ $email = \OC::$server->getConfig()->getUserValue($notif->getUserId(), 'settings', 'email');
+ if(strlen($email) === 0 || !isset($email)) continue;
+ $url = \OC::$server->getURLGenerator()->getAbsoluteURL(\OC::$server->getURLGenerator()->linkToRoute('polls.page.goto_poll', array('hash' => $poll->getHash())));
+
+ $msg = $l->t('Hello %s,<br/><br/><strong>%s</strong> participated in the poll \'%s\'.<br/><br/>To go directly to the poll, you can use this <a href="%s">link</a>', array(
+ $userMgr->get($notif->getUserId())->getDisplayName(), $userMgr->get($from)->getDisplayName(), $poll->getTitle(), $url));
+
+ $msg .= "<br/><br/>";
+
+ $toname = $userMgr->get($notif->getUserId())->getDisplayName();
+ $subject = $l->t('ownCloud Polls - New Comment');
+ $fromaddress = \OCP\Util::getDefaultEmailAddress('no-reply');
+ $fromname = $l->t("ownCloud Polls") . ' (' . $from . ')';
+
+ try {
+ $mailer = \OC::$server->getMailer();
+ $message = $mailer->createMessage();
+ $message->setSubject($subject);
+ $message->setFrom(array($fromaddress => $fromname));
+ $message->setTo(array($email => $toname));
+ $message->setBody($msg);
+ $mailer->send($message);
+ } catch (\Exception $e) {
+ $message = 'error sending mail to: ' . $toname . ' (' . $email . ')';
+ \OCP\Util::writeLog("polls", $message, \OCP\Util::ERROR);
+ }
+ }
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
+ */
+ public function gotoPoll($hash) {
+ $poll = $this->eventMapper->findByHash($hash);
+ if($poll->getType() === '0') $dates = $this->dateMapper->findByPoll($poll->getId());
+ else $dates = $this->textMapper->findByPoll($poll->getId());
+ $comments = $this->commentMapper->findByPoll($poll->getId());
+ $votes = $this->participationMapper->findByPoll($poll->getId());
+ try {
+ $notification = $this->notificationMapper->findByUserAndPoll($poll->getId(), $this->userId);
+ } catch(\OCP\AppFramework\Db\DoesNotExistException $e) {
+ $notification = null;
+ }
+ if($this->hasUserAccess($poll)) return new TemplateResponse('polls', 'goto.tmpl', ['poll' => $poll, 'dates' => $dates, 'comments' => $comments, 'votes' => $votes, 'notification' => $notification, 'userId' => $this->userId, 'userMgr' => $this->manager, 'urlGenerator' => $this->urlGenerator]);
+ else return new TemplateResponse('polls', 'no.acc.tmpl', []);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function deletePoll($pollId) {
+ $poll = new Event();
+ $poll->setId($pollId);
+ $this->eventMapper->delete($poll);
+ $this->textMapper->deleteByPoll($pollId);
+ $this->dateMapper->deleteByPoll($pollId);
+ $this->participationMapper->deleteByPoll($pollId);
+ $this->commentMapper->deleteByPoll($pollId);
+ $url = $this->urlGenerator->linkToRoute('polls.page.index');
+ return new RedirectResponse($url);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function editPoll($hash) {
+ $poll = $this->eventMapper->findByHash($hash);
+ if($this->userId !== $poll->getOwner()) return new TemplateResponse('polls', 'no.create.tmpl');
+ if($poll->getType() === '0') $dates = $this->dateMapper->findByPoll($poll->getId());
+ else $dates = $this->textMapper->findByPoll($poll->getId());
+ return new TemplateResponse('polls', 'create.tmpl', ['poll' => $poll, 'dates' => $dates, 'userId' => $this->userId, 'userMgr' => $this->manager, 'urlGenerator' => $this->urlGenerator]);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function updatePoll($pollId, $pollType, $pollTitle, $pollDesc, $userId, $chosenDates, $expireTs, $accessType, $accessValues) {
+ $event = $this->eventMapper->find($pollId);
+ $event->setTitle(htmlspecialchars($pollTitle));
+ $event->setDescription(htmlspecialchars($pollDesc));
+
+ if($accessType === 'select') {
+ if (isset($accessValues)) {
+ $accessValues = json_decode($accessValues);
+ if($accessValues !== null) {
+ $groups = array();
+ $users = array();
+ if($accessValues->groups !== null) $groups = $accessValues->groups;
+ if($accessValues->users !== null) $users = $accessValues->users;
+ $accessType = '';
+ foreach ($groups as $gid) {
+ $accessType .= 'group_' . $gid . ';';
+ }
+ foreach ($users as $uid) {
+ $accessType .= 'user_' . $uid . ';';
+ }
+ }
+ }
+ }
+ $event->setAccess($accessType);
+
+ $chosenDates = json_decode($chosenDates);
+
+ $expire = null;
+ if($expireTs !== null && $expireTs !== '') {
+ $expire = date('Y-m-d H:i:s', $expireTs + 60*60*24); //add one day, so it expires at the end of a day
+ }
+ $event->setExpire($expire);
+
+ $this->dateMapper->deleteByPoll($pollId);
+ $this->textMapper->deleteByPoll($pollId);
+ if($pollType === 'event') {
+ $event->setType(0);
+ $this->eventMapper->update($event);
+ sort($chosenDates);
+ foreach ($chosenDates as $el) {
+ $date = new Date();
+ $date->setPollId($pollId);
+ $date->setDt(date('Y-m-d H:i:s', $el));
+ $this->dateMapper->insert($date);
+ }
+ } else {
+ $event->setType(1);
+ $this->eventMapper->update($event);
+ foreach($chosenDates as $el) {
+ $text = new Text();
+ $text->setText($el);
+ $text->setPollId($pollId);
+ $this->textMapper->insert($text);
+ }
+ }
+ $url = $this->urlGenerator->linkToRoute('polls.page.index');
+ return new RedirectResponse($url);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function createPoll() {
+ return new TemplateResponse('polls', 'create.tmpl', ['userId' => $this->userId, 'userMgr' => $this->manager, 'urlGenerator' => $this->urlGenerator]);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function insertPoll($pollType, $pollTitle, $pollDesc, $userId, $chosenDates, $expireTs, $accessType, $accessValues) {
+ $event = new Event();
+ $event->setTitle(htmlspecialchars($pollTitle));
+ $event->setDescription(htmlspecialchars($pollDesc));
+ $event->setOwner($userId);
+ $event->setCreated(date('Y-m-d H:i:s'));
+ $event->setHash(\OC::$server->getSecureRandom()->getMediumStrengthGenerator()->generate(16));
+
+ $accessValues = json_decode($accessValues);
+ $groups = $accessValues->groups;
+ $users = $accessValues->users;
+ if ($accessType === 'select') {
+ $accessType = '';
+ foreach ($groups as $gid) {
+ $accessType .= 'group_' . $gid . ';';
+ }
+ foreach ($users as $uid) {
+ $accessType .= 'user_' . $uid . ';';
+ }
+ }
+ $event->setAccess($accessType);
+
+ $chosenDates = json_decode($chosenDates);
+
+ $expire = null;
+ if($expireTs !== null) {
+ $expire = date('Y-m-d H:i:s', $expireTs + 60*60*24); //add one day, so it expires at the end of a day
+ }
+ $event->setExpire($expire);
+
+ $poll_id = -1;
+ if($pollType === 'event') {
+ $event->setType(0);
+ $ins = $this->eventMapper->insert($event);
+ $poll_id = $ins->getId();
+ sort($chosenDates);
+ foreach ($chosenDates as $el) {
+ $date = new Date();
+ $date->setPollId($poll_id);
+ $date->setDt(date('Y-m-d H:i:s', $el));
+ $this->dateMapper->insert($date);
+ }
+ } else {
+ $event->setType(1);
+ foreach($chosenDates as $el) {
+ $text = new Text();
+ $text->setText($el);
+ $text->setPollId($pollId);
+ $this->textMapper->insert($text);
+ }
+ }
+ $url = $this->urlGenerator->linkToRoute('polls.page.index');
+ return new RedirectResponse($url);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ * @PublicPage
+ */
+ public function insertVote($pollId, $userId, $types, $dates, $notif, $changed) {
+ if($changed === 'true') {
+ if($this->userId !== null) {
+ if($notif === 'true') {
+ try {
+ //check if user already set notification for this poll
+ $this->notificationMapper->findByUserAndPoll($pollId, $userId);
+ } catch(\OCP\AppFramework\Db\DoesNotExistException $e) {
+ //insert if not exist
+ $not = new Notification();
+ $not->setUserId($userId);
+ $not->setPollId($pollId);
+ $this->notificationMapper->insert($not);
+ }
+ } else {
+ try {
+ //delete if entry is in db
+ $not = $this->notificationMapper->findByUserAndPoll($pollId, $userId);
+ $this->notificationMapper->delete($not);
+ } catch(\OCP\AppFramework\Db\DoesNotExistException $e) {
+ //doesn't exist in db, nothing to do
+ }
+ }
+ } else {
+ $userId = $userId . ' (extern)';
+ }
+
+ $dates = json_decode($dates);
+ $types = json_decode($types);
+ for($i=0; $i<count($dates); $i++) {
+ $part = new Participation();
+ $part->setPollId($pollId);
+ $part->setUserId($userId);
+ $part->setDt(date('Y-m-d H:i:s', $dates[$i]));
+ $part->setType($types[$i]);
+ $this->participationMapper->insert($part);
+ }
+ $this->sendNotifications($pollId, $userId);
+ }
+ $hash = $this->eventMapper->find($pollId)->getHash();
+ $url = $this->urlGenerator->linkToRoute('polls.page.goto_poll', ['hash' => $hash]);
+ return new RedirectResponse($url);
+ }
+
+ /**
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ */
+ public function insertComment($pollId, $userId, $commentBox) {
+ $comment = new Comment();
+ $comment->setPollId($pollId);
+ $comment->setUserId($userId);
+ $comment->setComment($commentBox);
+ $comment->setDt(date('Y-m-d H:i:s'));
+ $this->commentMapper->insert($comment);
+ $this->sendNotifications($pollId, $userId);
+ $hash = $this->eventMapper->find($pollId)->getHash();
+ $url = $this->urlGenerator->linkToRoute('polls.page.goto_poll', ['hash' => $hash]);
+ return new RedirectResponse($url);
+ }
+
+ public function getPollsForUser() {
+ return $this->eventMapper->findAllForUser($this->userId);
+ }
+
+ public function getPollsForUserWithInfo($user = null) {
+ if($user === null) return $this->eventMapper->findAllForUserWithInfo($this->userId);
+ else return $this->eventMapper->findAllForUserWithInfo($user);
+ }
+
+ private function hasUserAccess($poll) {
+ $access = $poll->getAccess();
+ if ($access === 'public') return true;
+ if ($access === 'hidden') return true;
+ if ($this->userId === null) return false;
+ if ($access === 'registered') return true;
+ if ($owner === $this->userId) return true;
+ $user_groups = OC_Group::getUserGroups($this->userId);
+ $arr = explode(';', $access);
+ foreach ($arr as $item) {
+ if (strpos($item, 'group_') === 0) {
+ $grp = substr($item, 6);
+ foreach ($user_groups as $user_group) {
+ if ($user_group === $grp) return true;
+ }
+ }
+ else if (strpos($item, 'user_') === 0) {
+ $usr = substr($item, 5);
+ if ($usr === User::getUser()) return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/css/jquery.datetimepicker.css b/css/jquery.datetimepicker.css
new file mode 100644
index 00000000..beda1458
--- /dev/null
+++ b/css/jquery.datetimepicker.css
@@ -0,0 +1,568 @@
+.xdsoft_datetimepicker {
+ box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.506);
+ background: #fff;
+ border-bottom: 1px solid #bbb;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #ccc;
+ border-top: 1px solid #ccc;
+ color: #333;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ padding: 8px;
+ padding-left: 0;
+ padding-top: 2px;
+ position: absolute;
+ z-index: 9999;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: none;
+}
+.xdsoft_datetimepicker.xdsoft_rtl {
+ padding: 8px 0 8px 8px;
+}
+
+.xdsoft_datetimepicker iframe {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 75px;
+ height: 210px;
+ background: transparent;
+ border: none;
+}
+
+/*For IE8 or lower*/
+.xdsoft_datetimepicker button {
+ border: none !important;
+}
+
+.xdsoft_noselect {
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+
+.xdsoft_noselect::selection { background: transparent }
+.xdsoft_noselect::-moz-selection { background: transparent }
+
+.xdsoft_datetimepicker.xdsoft_inline {
+ display: inline-block;
+ position: static;
+ box-shadow: none;
+}
+
+.xdsoft_datetimepicker * {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0;
+ margin: 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_datepicker, .xdsoft_datetimepicker .xdsoft_timepicker {
+ display: none;
+}
+
+.xdsoft_datetimepicker .xdsoft_datepicker.active, .xdsoft_datetimepicker .xdsoft_timepicker.active {
+ display: block;
+}
+
+.xdsoft_datetimepicker .xdsoft_datepicker {
+ width: 224px;
+ float: left;
+ margin-left: 8px;
+}
+.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_datepicker {
+ float: right;
+ margin-right: 8px;
+ margin-left: 0;
+}
+
+.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_datepicker {
+ width: 256px;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker {
+ width: 58px;
+ float: left;
+ text-align: center;
+ margin-left: 8px;
+ margin-top: 0;
+}
+.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker {
+ float: right;
+ margin-right: 8px;
+ margin-left: 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_datepicker.active+.xdsoft_timepicker {
+ margin-top: 8px;
+ margin-bottom: 3px
+}
+
+.xdsoft_datetimepicker .xdsoft_mounthpicker {
+ position: relative;
+ text-align: center;
+}
+
+.xdsoft_datetimepicker .xdsoft_label i,
+.xdsoft_datetimepicker .xdsoft_prev,
+.xdsoft_datetimepicker .xdsoft_next,
+.xdsoft_datetimepicker .xdsoft_today_button {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Q0NBRjI1NjM0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6Q0NBRjI1NjQ0M0UwMTFFNDk4NkFGMzJFQkQzQjEwRUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDQ0FGMjU2MTQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDQ0FGMjU2MjQzRTAxMUU0OTg2QUYzMkVCRDNCMTBFQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoNEP54AAAIOSURBVHja7Jq9TsMwEMcxrZD4WpBYeKUCe+kTMCACHZh4BFfHO/AAIHZGFhYkBBsSEqxsLCAgXKhbXYOTxh9pfJVP+qutnZ5s/5Lz2Y5I03QhWji2GIcgAokWgfCxNvcOCCGKqiSqhUp0laHOne05vdEyGMfkdxJDVjgwDlEQgYQBgx+ULJaWSXXS6r/ER5FBVR8VfGftTKcITNs+a1XpcFoExREIDF14AVIFxgQUS+h520cdud6wNkC0UBw6BCO/HoCYwBhD8QCkQ/x1mwDyD4plh4D6DDV0TAGyo4HcawLIBBSLDkHeH0Mg2yVP3l4TQMZQDDsEOl/MgHQqhMNuE0D+oBh0CIr8MAKyazBH9WyBuKxDWgbXfjNf32TZ1KWm/Ap1oSk/R53UtQ5xTh3LUlMmT8gt6g51Q9p+SobxgJQ/qmsfZhWywGFSl0yBjCLJCMgXail3b7+rumdVJ2YRss4cN+r6qAHDkPWjPjdJCF4n9RmAD/V9A/Wp4NQassDjwlB6XBiCxcJQWmZZb8THFilfy/lfrTvLghq2TqTHrRMTKNJ0sIhdo15RT+RpyWwFdY96UZ/LdQKBGjcXpcc1AlSFEfLmouD+1knuxBDUVrvOBmoOC/rEcN7OQxKVeJTCiAdUzUJhA2Oez9QTkp72OTVcxDcXY8iKNkxGAJXmJCOQwOa6dhyXsOa6XwEGAKdeb5ET3rQdAAAAAElFTkSuQmCC);
+}
+
+.xdsoft_datetimepicker .xdsoft_label i {
+ opacity: 0.5;
+ background-position: -92px -19px;
+ display: inline-block;
+ width: 9px;
+ height: 20px;
+ vertical-align: middle;
+}
+
+.xdsoft_datetimepicker .xdsoft_prev {
+ float: left;
+ background-position: -20px 0;
+}
+.xdsoft_datetimepicker .xdsoft_today_button {
+ float: left;
+ background-position: -70px 0;
+ margin-left: 5px;
+}
+
+.xdsoft_datetimepicker .xdsoft_next {
+ float: right;
+ background-position: 0 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_next,
+.xdsoft_datetimepicker .xdsoft_prev ,
+.xdsoft_datetimepicker .xdsoft_today_button {
+ background-color: transparent;
+ background-repeat: no-repeat;
+ border: 0 none;
+ cursor: pointer;
+ display: block;
+ height: 30px;
+ opacity: 0.5;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
+ outline: medium none;
+ overflow: hidden;
+ padding: 0;
+ position: relative;
+ text-indent: 100%;
+ white-space: nowrap;
+ width: 20px;
+ min-width: 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_next {
+ float: none;
+ background-position: -40px -15px;
+ height: 15px;
+ width: 30px;
+ display: block;
+ margin-left: 14px;
+ margin-top: 7px;
+}
+.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker .xdsoft_prev,
+.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_timepicker .xdsoft_next {
+ float: none;
+ margin-left: 0;
+ margin-right: 14px;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_prev {
+ background-position: -40px 0;
+ margin-bottom: 7px;
+ margin-top: 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box {
+ height: 151px;
+ overflow: hidden;
+ border-bottom: 1px solid #ddd;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div {
+ background: #f5f5f5;
+ border-top: 1px solid #ddd;
+ color: #666;
+ font-size: 12px;
+ text-align: center;
+ border-collapse: collapse;
+ cursor: pointer;
+ border-bottom-width: 0;
+ height: 25px;
+ line-height: 25px;
+}
+
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div > div:first-child {
+ border-top-width: 0;
+}
+
+.xdsoft_datetimepicker .xdsoft_today_button:hover,
+.xdsoft_datetimepicker .xdsoft_next:hover,
+.xdsoft_datetimepicker .xdsoft_prev:hover {
+ opacity: 1;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
+}
+
+.xdsoft_datetimepicker .xdsoft_label {
+ display: inline;
+ position: relative;
+ z-index: 9999;
+ margin: 0;
+ padding: 5px 3px;
+ font-size: 14px;
+ line-height: 20px;
+ font-weight: bold;
+ background-color: #fff;
+ float: left;
+ width: 182px;
+ text-align: center;
+ cursor: pointer;
+}
+
+.xdsoft_datetimepicker .xdsoft_label:hover>span {
+ text-decoration: underline;
+}
+
+.xdsoft_datetimepicker .xdsoft_label:hover i {
+ opacity: 1.0;
+}
+
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select {
+ border: 1px solid #ccc;
+ position: absolute;
+ right: 0;
+ top: 30px;
+ z-index: 101;
+ display: none;
+ background: #fff;
+ max-height: 160px;
+ overflow-y: hidden;
+}
+
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_monthselect{ right: -7px }
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select.xdsoft_yearselect{ right: 2px }
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover {
+ color: #fff;
+ background: #ff8000;
+}
+
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option {
+ padding: 2px 10px 2px 5px;
+ text-decoration: none !important;
+}
+
+.xdsoft_datetimepicker .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current {
+ background: #33aaff;
+ box-shadow: #178fe5 0 1px 3px 0 inset;
+ color: #fff;
+ font-weight: 700;
+}
+
+.xdsoft_datetimepicker .xdsoft_month {
+ width: 100px;
+ text-align: right;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar {
+ clear: both;
+}
+
+.xdsoft_datetimepicker .xdsoft_year{
+ width: 48px;
+ margin-left: 5px;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar table {
+ border-collapse: collapse;
+ width: 100%;
+
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td > div {
+ padding-right: 5px;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar th {
+ height: 25px;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td,.xdsoft_datetimepicker .xdsoft_calendar th {
+ width: 14.2857142%;
+ background: #f5f5f5;
+ border: 1px solid #ddd;
+ color: #666;
+ font-size: 12px;
+ text-align: right;
+ vertical-align: middle;
+ padding: 0;
+ border-collapse: collapse;
+ cursor: pointer;
+ height: 25px;
+}
+.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar td,.xdsoft_datetimepicker.xdsoft_showweeks .xdsoft_calendar th {
+ width: 12.5%;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar th {
+ background: #f1f1f1;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_today {
+ color: #33aaff;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_default {
+ background: #ffe9d2;
+ box-shadow: #ffb871 0 1px 4px 0 inset;
+ color: #000;
+}
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_highlighted_mint {
+ background: #c1ffc9;
+ box-shadow: #00dd1c 0 1px 4px 0 inset;
+ color: #000;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_default,
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_current {
+ background: #33aaff;
+ box-shadow: #178fe5 0 1px 3px 0 inset;
+ color: #fff;
+ font-weight: 700;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month,
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled,
+.xdsoft_datetimepicker .xdsoft_time_box >div >div.xdsoft_disabled {
+ opacity: 0.5;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
+ cursor: default;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_other_month.xdsoft_disabled {
+ opacity: 0.2;
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=20)";
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td:hover,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div:hover {
+ color: #fff !important;
+ background: #ff8000 !important;
+ box-shadow: none !important;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_current.xdsoft_disabled:hover,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box>div>div.xdsoft_current.xdsoft_disabled:hover {
+ background: #33aaff !important;
+ box-shadow: #178fe5 0 1px 3px 0 inset !important;
+ color: #fff !important;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar td.xdsoft_disabled:hover,
+.xdsoft_datetimepicker .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_disabled:hover {
+ color: inherit !important;
+ background: inherit !important;
+ box-shadow: inherit !important;
+}
+
+.xdsoft_datetimepicker .xdsoft_calendar th {
+ font-weight: 700;
+ text-align: center;
+ color: #999;
+ cursor: default;
+}
+
+.xdsoft_datetimepicker .xdsoft_copyright {
+ color: #ccc !important;
+ font-size: 10px;
+ clear: both;
+ float: none;
+ margin-left: 8px;
+}
+
+.xdsoft_datetimepicker .xdsoft_copyright a { color: #eee !important }
+.xdsoft_datetimepicker .xdsoft_copyright a:hover { color: #aaa !important }
+
+.xdsoft_time_box {
+ position: relative;
+ border: 1px solid #ccc;
+}
+.xdsoft_scrollbar >.xdsoft_scroller {
+ background: #ccc !important;
+ height: 20px;
+ border-radius: 3px;
+}
+.xdsoft_scrollbar {
+ position: absolute;
+ width: 7px;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ cursor: pointer;
+}
+.xdsoft_datetimepicker.xdsoft_rtl .xdsoft_scrollbar {
+ left: 0;
+ right: auto;
+}
+.xdsoft_scroller_box {
+ position: relative;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark {
+ box-shadow: 0 5px 15px -5px rgba(255, 255, 255, 0.506);
+ background: #000;
+ border-bottom: 1px solid #444;
+ border-left: 1px solid #333;
+ border-right: 1px solid #333;
+ border-top: 1px solid #333;
+ color: #ccc;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box {
+ border-bottom: 1px solid #222;
+}
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div {
+ background: #0a0a0a;
+ border-top: 1px solid #222;
+ color: #999;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label {
+ background-color: #000;
+}
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select {
+ border: 1px solid #333;
+ background: #000;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select > div > .xdsoft_option:hover {
+ color: #000;
+ background: #007fff;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label > .xdsoft_select > div > .xdsoft_option.xdsoft_current {
+ background: #cc5500;
+ box-shadow: #b03e00 0 1px 3px 0 inset;
+ color: #000;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_label i,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_prev,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_next,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_today_button {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAeCAYAAADaW7vzAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QUExQUUzOTA0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QUExQUUzOTE0M0UyMTFFNDlBM0FFQTJENTExRDVBODYiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpBQTFBRTM4RTQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpBQTFBRTM4RjQzRTIxMUU0OUEzQUVBMkQ1MTFENUE4NiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pp0VxGEAAAIASURBVHja7JrNSgMxEMebtgh+3MSLr1T1Xn2CHoSKB08+QmR8Bx9A8e7RixdB9CKCoNdexIugxFlJa7rNZneTbLIpM/CnNLsdMvNjM8l0mRCiQ9Ye61IKCAgZAUnH+mU3MMZaHYChBnJUDzWOFZdVfc5+ZFLbrWDeXPwbxIqrLLfaeS0hEBVGIRQCEiZoHQwtlGSByCCdYBl8g8egTTAWoKQMRBRBcZxYlhzhKegqMOageErsCHVkk3hXIFooDgHB1KkHIHVgzKB4ADJQ/A1jAFmAYhkQqA5TOBtocrKrgXwQA8gcFIuAIO8sQSA7hidvPwaQGZSaAYHOUWJABhWWw2EMIH9QagQERU4SArJXo0ZZL18uvaxejXt/Em8xjVBXmvFr1KVm/AJ10tRe2XnraNqaJvKE3KHuUbfK1E+VHB0q40/y3sdQSxY4FHWeKJCunP8UyDdqJZenT3ntVV5jIYCAh20vT7ioP8tpf6E2lfEMwERe+whV1MHjwZB7PBiCxcGQWwKZKD62lfGNnP/1poFAA60T7rF1UgcKd2id3KDeUS+oLWV8DfWAepOfq00CgQabi9zjcgJVYVD7PVzQUAUGAQkbNJTBICDhgwYTjDYD6XeW08ZKh+A4pYkzenOxXUbvZcWz7E8ykRMnIHGX1XPl+1m2vPYpL+2qdb8CDAARlKFEz/ZVkAAAAABJRU5ErkJggg==);
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
+ background: #0a0a0a;
+ border: 1px solid #222;
+ color: #999;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
+ background: #0e0e0e;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_today {
+ color: #cc5500;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_default {
+ background: #ffe9d2;
+ box-shadow: #ffb871 0 1px 4px 0 inset;
+ color:#000;
+}
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_highlighted_mint {
+ background: #c1ffc9;
+ box-shadow: #00dd1c 0 1px 4px 0 inset;
+ color:#000;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_default,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td.xdsoft_current,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div.xdsoft_current {
+ background: #cc5500;
+ box-shadow: #b03e00 0 1px 3px 0 inset;
+ color: #000;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar td:hover,
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_timepicker .xdsoft_time_box >div >div:hover {
+ color: #000 !important;
+ background: #007fff !important;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_calendar th {
+ color: #666;
+}
+
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright { color: #333 !important }
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a { color: #111 !important }
+.xdsoft_datetimepicker.xdsoft_dark .xdsoft_copyright a:hover { color: #555 !important }
+
+.xdsoft_dark .xdsoft_time_box {
+ border: 1px solid #333;
+}
+
+.xdsoft_dark .xdsoft_scrollbar >.xdsoft_scroller {
+ background: #333 !important;
+}
+.xdsoft_datetimepicker .xdsoft_save_selected {
+ display: block;
+ border: 1px solid #dddddd !important;
+ margin-top: 5px;
+ width: 100%;
+ color: #454551;
+ font-size: 13px;
+}
+.xdsoft_datetimepicker .blue-gradient-button {
+ font-family: "museo-sans", "Book Antiqua", sans-serif;
+ font-size: 12px;
+ font-weight: 300;
+ color: #82878c;
+ height: 28px;
+ position: relative;
+ padding: 4px 17px 4px 33px;
+ border: 1px solid #d7d8da;
+ background: -moz-linear-gradient(top, #fff 0%, #f4f8fa 73%);
+ /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff), color-stop(73%, #f4f8fa));
+ /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #fff 0%, #f4f8fa 73%);
+ /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #fff 0%, #f4f8fa 73%);
+ /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #fff 0%, #f4f8fa 73%);
+ /* IE10+ */
+ background: linear-gradient(to bottom, #fff 0%, #f4f8fa 73%);
+ /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff', endColorstr='#f4f8fa',GradientType=0 );
+/* IE6-9 */
+}
+.xdsoft_datetimepicker .blue-gradient-button:hover, .xdsoft_datetimepicker .blue-gradient-button:focus, .xdsoft_datetimepicker .blue-gradient-button:hover span, .xdsoft_datetimepicker .blue-gradient-button:focus span {
+ color: #454551;
+ background: -moz-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
+ /* FF3.6+ */
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #f4f8fa), color-stop(73%, #FFF));
+ /* Chrome,Safari4+ */
+ background: -webkit-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
+ /* Chrome10+,Safari5.1+ */
+ background: -o-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
+ /* Opera 11.10+ */
+ background: -ms-linear-gradient(top, #f4f8fa 0%, #FFF 73%);
+ /* IE10+ */
+ background: linear-gradient(to bottom, #f4f8fa 0%, #FFF 73%);
+ /* W3C */
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f8fa', endColorstr='#FFF',GradientType=0 );
+ /* IE6-9 */
+}
diff --git a/css/main.css b/css/main.css
new file mode 100644
index 00000000..d9042ae7
--- /dev/null
+++ b/css/main.css
@@ -0,0 +1,409 @@
+#content-wrapper {
+ position: relative;
+}
+
+body {
+ margin: 10px;
+}
+
+h1 {
+ font-size: 2em;
+ margin-bottom: 15px;
+}
+
+h2 {
+ font-size: 1.5em;
+ margin: 10px 0 5px 0;
+}
+
+footer {
+ text-align: center;
+ color: #777;
+}
+
+th, tr, td {
+ padding: 4px;
+ text-align: center;
+}
+
+th {
+ font-weight: bold;
+}
+
+tr:nth-child(even), tr:nth-child(even) a {
+ background: #35537a;
+ color: #eee;
+}
+
+tr:nth-child(odd) {
+}
+
+table {
+ border: 1px solid #aaa;
+ border-radius: 3px;
+}
+
+.goto_poll {
+ width: 100%;
+}
+
+input.input_field {
+ width: 20%;
+}
+
+.label_h1 {
+ display:block;
+}
+
+div.new_poll {
+ width: 100%;
+}
+
+div.goto_poll {
+ /*background-color: #82de82;*/
+}
+
+div.partic_all {
+ width: 10px;
+ height: 10px;
+ display: inline-block;
+}
+
+div.partic_yes {
+ background-color: #6fff70; /*green*/
+}
+
+div.partic_no {
+ background-color: #ff6f6f; /*red*/
+}
+
+input.table_button {
+ background-color: transparent;
+ border: none;
+ height: 12px;
+ width: 12px;
+ vertical-align: middle;
+}
+
+div.scroll_div {
+ width: 100%;
+ overflow-x: auto;
+ overflow-y: hidden;
+}
+
+div.scroll_div_dialog {
+ width: 100%;
+ height: 250px;
+ overflow-y: auto;
+}
+
+td.td_shown {
+ visibility: visible;
+}
+
+.td_hidden {
+ visibility: hidden;
+ visibility: collapse;
+}
+
+.td_selected {
+ background-color: #82de82;
+}
+
+.td_deselected {
+ background-color: white;
+}
+
+.cl_with_border td {
+ padding-right: 15px;
+ padding: 1px;
+ border-width: 1px;
+ border-style: solid;
+ border-color: gray;
+ -moz-border-radius: initial;
+ text-align: center;
+ vertical-align: bottom;
+ cursor: pointer;
+}
+.scrollable_table {
+ table-layout: fixed;
+}
+
+.desc {
+ color: #888;
+}
+
+.wordwrap {
+ width: 75%;
+ white-space: normal;
+ word-wrap: break-word;
+ word-break: normal;
+}
+
+.cl_title {
+ font-size: 2em;
+}
+
+.input_title{
+ font-size: 1.2em;
+}
+.padded td {
+ padding: 10px;
+}
+
+.cl_create_form, .vote_table {
+ min-width: 60%;
+ margin-bottom: 10px;
+}
+
+.vote_table {
+ margin-top: 10px;
+}
+
+.cl_create_form td {
+ padding: 3px;
+ text-align: left;
+ vertical-align: center;
+ text-align: center;
+}
+
+.cl_time_display {
+ background-color: aqua;
+ cursor: pointer;
+}
+.cl_date_time_header:hover {
+ background-color: red;
+}
+.cl_hour, .cl_min {
+ cursor: pointer;
+ background-color: white;
+}
+.cl_hour_selected, .cl_min_selected {
+ background-color: #82de82;
+}
+
+.cl_poll_access, .cl_poll_url, .cl_click, .cl_delete, .cl_date_time_header {
+ cursor: pointer;
+}
+
+.cl_delete {
+ background-color: white;
+ border-top: 1px solid gray;
+ border-bottom: 1px solid gray;
+}
+
+.cl_pad_left {
+ padding-left: 30px;
+}
+
+.cl_del_item {
+ cursor: pointer;
+ padding: 0px 5px 0px 5px;
+
+}
+.cl_del_item:hover {
+ background-color: #ffccca;
+}
+.cl_maybe:before, .cl_maybe:after{
+ content: "?";
+}
+.cl_total_y {
+ background-color: #6fff70; /*green*/
+}
+.cl_total_n {
+ background-color: #ff6f6f; /*red*/
+}
+
+.win_row {
+ color: #5ef56c;
+ font-size: 2em;
+}
+
+.cl_user_comments {
+ table-layout: fixed;
+}
+
+.cl_user_comments td {
+ text-align: left;
+}
+
+.cl_user_comments th {
+ word-wrap: break-word;
+ vertical-align: top;
+ text-align: center;
+}
+
+.user_comment {
+ font-size: 0.9em;
+}
+
+.user_comment {
+ padding-bottom: 10px;
+}
+
+.user_comment_text {
+ margin-top: -5px;
+ margin-left: 5px;
+}
+
+.date {
+ font-size: 0.8em;
+ color: #555;
+}
+
+#id_tab_total {
+ height: 2em;
+ width: 100%;
+ text-align: center;
+}
+
+#id_tab_total tr:nth-child(even) {
+ color: #000;
+}
+
+#id_cal_table td {
+ padding: 10px;
+}
+#id_time_table td {
+ padding: 8px;
+}
+#id_poss_table td {
+ padding-left: 2px;
+}
+
+/* users, groups... */
+#dialog-overlay {
+ /* set it to fill the whil screen */
+ width:100%;
+ height:100%;
+
+ /* transparency for different browsers */
+ filter:alpha(opacity=50);
+ -moz-opacity:0.5;
+ -khtml-opacity: 0.5;
+ opacity: 0.5;
+ background:#000;
+ /* make sure it appear behind the dialog box but above everything else */
+ position:absolute;
+ top:0; left:0;
+ z-index:3000;
+ /* hide it by default */
+ display:none;
+}
+
+#text-title, #id_expire_date {
+ margin-left: 5px;
+}
+
+#dialog-box {
+ padding: 10px;
+ /* css3 drop shadow */
+ -webkit-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
+ -moz-box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
+ box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
+ /* css3 border radius */
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+
+ background:#eee;
+ /* styling of the dialog box, i have a fixed dimension for this demo */
+ width:400px;
+ /* make sure it has the highest z-index */
+ position:absolute;
+ z-index:5000;
+ /* hide it by default */
+ display:none;
+}
+
+div#dialog-message {
+ padding: 0 0 20px 0;
+}
+
+#table_groups, #table_users {
+ width: 100%;
+ padding: 20px 5px 10px 5px;
+ table-layout: fixed;
+ overflow-y: auto;
+}
+
+#table_users {
+ padding-left: 10px;
+}
+
+.cl_group_item, .cl_user_item {
+ background-color: white;
+ color: #000000;
+}
+.cl_group_item_selected, .cl_user_item_selected {
+ background-color: #1d2d44;
+ color: #8e96a1;
+}
+
+/* STUFF FROM mypolls */
+ul {
+ padding: 5px;
+ padding-left: 12px;
+}
+
+#app-content {
+ padding: 5px;
+}
+
+#polls {
+ width: 100%;
+}
+
+#poll-table {
+ width: 100%;
+}
+
+#poll-desc, #comments-container, #poll-dates {
+ margin-bottom: 15px;
+}
+
+#comment-text {
+ display: block;
+}
+
+#datepicker {
+ float: left;
+ padding-right: 15px;
+}
+
+#new-poll-form-warn {
+ color: red;
+}
+
+#poll-dates table {
+ min-width: 50%;
+}
+
+#check_notif {
+ margin-bottom: 10px;
+}
+
+.poll-cell-not, .poll-cell-is, .poll-cell-maybe, .poll-cell-un {
+ height: 24px;
+}
+
+.poll-cell-un, .poll-cell-active-un {
+ background-color: #fff;
+}
+
+.poll-cell-is, .poll-cell-active-is {
+ background-color: #6fff70; /*green*/
+}
+
+.poll-cell-maybe, .poll-cell-active-maybe {
+ background-color: #fcff6f; /*yellow*/
+}
+
+.poll-cell-not, .poll-cell-active-not {
+ background-color: #ff6f6f; /*red*/
+}
+
+.date-row:hover {
+ background-color: red;
+ color: black;
+}
diff --git a/db/access.php b/db/access.php
new file mode 100644
index 00000000..e5af9bbd
--- /dev/null
+++ b/db/access.php
@@ -0,0 +1,15 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method integer getPId()
+ * @method void setPId(integer $value)
+ * @method string getAccessType()
+ * @method void setAccessType(string $value)
+ */
+class Access extends Entity {
+ public $pId;
+ public $accessType;
+}
diff --git a/db/accessmapper.php b/db/accessmapper.php
new file mode 100644
index 00000000..be863359
--- /dev/null
+++ b/db/accessmapper.php
@@ -0,0 +1,49 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class AccessMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_access', '\OCA\Polls\Db\Access');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Favorite
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_access` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Favorite[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_access` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Favorite[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_access`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+}
diff --git a/db/comment.php b/db/comment.php
new file mode 100644
index 00000000..c6fca666
--- /dev/null
+++ b/db/comment.php
@@ -0,0 +1,21 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getUserId()
+ * @method void setUserId(string $value)
+ * @method string getDt()
+ * @method void setDt(string $value)
+ * @method string getComment()
+ * @method void setComment(string $value)
+ * @method integer getPollId()
+ * @method void setPollId(integer $value)
+ */
+class Comment extends Entity {
+ public $userId;
+ public $dt;
+ public $comment;
+ public $pollId;
+}
diff --git a/db/commentmapper.php b/db/commentmapper.php
new file mode 100644
index 00000000..00f56e20
--- /dev/null
+++ b/db/commentmapper.php
@@ -0,0 +1,79 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class CommentMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_comments', '\OCA\Polls\Db\Comment');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Comment
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_comments` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Comment[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_comments` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Comment[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_comments`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param string $userId
+ * @param int $limit
+ * @param int $offset
+ * @return Comment[]
+ */
+ public function findDistinctByUser($userId, $limit=null, $offset=null) {
+ $sql = 'SELECT DISTINCT * FROM `*PREFIX*polls_comments` WHERE user_id=?';
+ return $this->findEntities($sql, [$userId], $limit, $offset);
+ }
+
+ /**
+ * @param string $userId
+ * @param int $limit
+ * @param int $offset
+ * @return Comment[]
+ */
+ public function findByPoll($pollId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_comments` WHERE poll_id=?';
+ return $this->findEntities($sql, [$pollId], $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ */
+ public function deleteByPoll($pollId) {
+ $sql = 'DELETE FROM `*PREFIX*polls_comments` WHERE poll_id=?';
+ $this->execute($sql, [$pollId], $limit, $offset);
+ }
+}
diff --git a/db/date.php b/db/date.php
new file mode 100644
index 00000000..c5bad99b
--- /dev/null
+++ b/db/date.php
@@ -0,0 +1,15 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method timestamp getDt()
+ * @method void setDt(timestamp $value)
+ * @method integer getPollId()
+ * @method void setPollId(integer $value
+ */
+class Date extends Entity {
+ public $dt;
+ public $pollId;
+}
diff --git a/db/datemapper.php b/db/datemapper.php
new file mode 100644
index 00000000..82f1a4b7
--- /dev/null
+++ b/db/datemapper.php
@@ -0,0 +1,68 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class DateMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_dts', '\OCA\Polls\Db\Date');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Date
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_dts` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Date[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_dts` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Date[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_dts`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ * @param int $limit
+ * @param int $offset
+ * @return Date[]
+ */
+ public function findByPoll($pollId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_dts` WHERE poll_id=?';
+ return $this->findEntities($sql, [$pollId], $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ */
+ public function deleteByPoll($pollId) {
+ $sql = 'DELETE FROM `*PREFIX*polls_dts` WHERE poll_id=?';
+ $this->execute($sql, [$pollId]);
+ }
+}
diff --git a/db/event.php b/db/event.php
new file mode 100644
index 00000000..b16a61d8
--- /dev/null
+++ b/db/event.php
@@ -0,0 +1,33 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method integer getType()
+ * @method void setType(integer $value)
+ * @method string getTitle()
+ * @method void setTitle(string $value)
+ * @method string getDescription()
+ * @method void setDescription(string $value)
+ * @method string getOwner()
+ * @method void setOwner(string $value)
+ * @method timestamp getCreated()
+ * @method void setCreated(timestamp $value)
+ * @method string getAccess()
+ * @method void setAccess(string $value)
+ * @method timestamp getExpire()
+ * @method void setExpire(timestamp $value)
+ * @method string getHash()
+ * @method void setHash(string $value)
+ */
+class Event extends Entity {
+ public $type;
+ public $title;
+ public $description;
+ public $owner;
+ public $created;
+ public $access;
+ public $expire;
+ public $hash;
+}
diff --git a/db/eventmapper.php b/db/eventmapper.php
new file mode 100644
index 00000000..5a172617
--- /dev/null
+++ b/db/eventmapper.php
@@ -0,0 +1,101 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class EventMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_events', '\OCA\Polls\Db\Event');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Event
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_events` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Event[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_events` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Event[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_events`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Event
+ */
+ public function findByHash($hash, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_events` WHERE `hash`=?';
+ return $this->findEntity($sql, [$hash], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Event[]
+ */
+ public function findAllForUser($userId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_events` WHERE `owner`=?';
+ return $this->findEntities($sql, [$userId], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Event[]
+ */
+ public function findAllForUserWithInfo($userId, $limit=null, $offset=null) {
+ $sql = 'SELECT DISTINCT *PREFIX*polls_events.id,
+ *PREFIX*polls_events.hash,
+ *PREFIX*polls_events.type,
+ *PREFIX*polls_events.title,
+ *PREFIX*polls_events.description,
+ *PREFIX*polls_events.owner,
+ *PREFIX*polls_events.created,
+ *PREFIX*polls_events.access,
+ *PREFIX*polls_events.expire
+ FROM *PREFIX*polls_events
+ LEFT JOIN *PREFIX*polls_particip
+ ON *PREFIX*polls_events.id = *PREFIX*polls_particip.id
+ LEFT JOIN *PREFIX*polls_comments
+ ON *PREFIX*polls_events.id = *PREFIX*polls_comments.id
+ WHERE
+ (*PREFIX*polls_events.access =? and *PREFIX*polls_events.owner =?)
+ OR
+ *PREFIX*polls_events.access !=?
+ OR
+ *PREFIX*polls_particip.user_id =?
+ OR
+ *PREFIX*polls_comments.user_id =?
+ ORDER BY created';
+ return $this->findEntities($sql, ['hidden', $userId, 'hidden', $userId, $userId], $limit, $offset);
+ }
+}
diff --git a/db/notification.php b/db/notification.php
new file mode 100644
index 00000000..2144fec9
--- /dev/null
+++ b/db/notification.php
@@ -0,0 +1,15 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getUserId()
+ * @method void setUserId(string $value)
+ * @method string getPollId()
+ * @method void setPollId(string $value)
+ */
+class Notification extends Entity {
+ public $userId;
+ public $pollId;
+}
diff --git a/db/notificationmapper.php b/db/notificationmapper.php
new file mode 100644
index 00000000..6abd4d77
--- /dev/null
+++ b/db/notificationmapper.php
@@ -0,0 +1,68 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class NotificationMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_notif', '\OCA\Polls\Db\Notification');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Notification
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_notif` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Notification[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_notif` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Notification[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_notif`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Notification[]
+ */
+ public function findAllByPoll($pollId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_notif` WHERE `poll_id`=?';
+ return $this->findEntities($sql, [$pollId], $limit, $offset);
+ }
+
+ /**
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @return Notification
+ */
+ public function findByUserAndPoll($pollId, $userId) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_notif` WHERE `poll_id`=? AND `user_id`=?';
+ return $this->findEntity($sql, [$pollId, $userId]);
+ }
+}
diff --git a/db/participation.php b/db/participation.php
new file mode 100644
index 00000000..c744f8f8
--- /dev/null
+++ b/db/participation.php
@@ -0,0 +1,21 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method timestamp getDt()
+ * @method void setDt(timestamp $value)
+ * @method string getUserId()
+ * @method void setUserId(string $value)
+ * @method integer getPollId()
+ * @method void setPollId(integer $value)
+ * @method integer getType()
+ * @method void setType(integer $value)
+ */
+class Participation extends Entity {
+ public $dt;
+ public $userId;
+ public $pollId;
+ public $type;
+}
diff --git a/db/participationmapper.php b/db/participationmapper.php
new file mode 100644
index 00000000..59e3b9d1
--- /dev/null
+++ b/db/participationmapper.php
@@ -0,0 +1,84 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class ParticipationMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_particip', '\OCA\Polls\Db\Participation');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Participation
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_particip` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ public function deleteByPollAndUser($pollId, $userId) {
+ $sql = 'DELETE FROM `*PREFIX*polls_particip` WHERE poll_id=? AND user_id=?';
+ $this->execute($sql, [$pollId, $userId]);
+ }
+
+ /**
+ * @param string $userId
+ * @param string $from
+ * @param string $until
+ * @param int $limit
+ * @param int $offset
+ * @return Participation[]
+ */
+ public function findBetween($userId, $from, $until, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_particip` '.
+ 'WHERE `userId` = ?'.
+ 'AND `timestamp` BETWEEN ? and ?';
+ return $this->findEntities($sql, [$userId, $from, $until], $limit, $offset);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Participation[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_particip`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param string $userId
+ * @param int $limit
+ * @param int $offset
+ * @return Participation[]
+ */
+ public function findDistinctByUser($userId, $limit=null, $offset=null) {
+ $sql = 'SELECT DISTINCT * FROM `*PREFIX*polls_particip` WHERE user_id=?';
+ return $this->findEntities($sql, [$userId], $limit, $offset);
+ }
+
+ /**
+ * @param string $userId
+ * @param int $limit
+ * @param int $offset
+ * @return Participation[]
+ */
+ public function findByPoll($pollId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_particip` WHERE poll_id=?';
+ return $this->findEntities($sql, [$pollId], $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ */
+ public function deleteByPoll($pollId) {
+ $sql = 'DELETE FROM `*PREFIX*polls_particip` WHERE poll_id=?';
+ $this->execute($sql, [$pollId], $limit, $offset);
+ }
+}
diff --git a/db/text.php b/db/text.php
new file mode 100644
index 00000000..dd2deb9e
--- /dev/null
+++ b/db/text.php
@@ -0,0 +1,15 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * @method string getText()
+ * @method void setText(string $value)
+ * @method integer getPollId()
+ * @method void setPollId(integer $value
+ */
+class Text extends Entity {
+ public $text;
+ public $pollId;
+}
diff --git a/db/textmapper.php b/db/textmapper.php
new file mode 100644
index 00000000..2ceff879
--- /dev/null
+++ b/db/textmapper.php
@@ -0,0 +1,53 @@
+<?php
+namespace OCA\Polls\Db;
+
+use OCP\AppFramework\Db\Mapper;
+use OCP\IDb;
+
+class TextMapper extends Mapper {
+
+ public function __construct(IDB $db) {
+ parent::__construct($db, 'polls_txts', '\OCA\Polls\Db\Text');
+ }
+
+ /**
+ * @param int $id
+ * @throws \OCP\AppFramework\Db\DoesNotExistException if not found
+ * @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
+ * @return Text
+ */
+ public function find($id) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_txts` '.
+ 'WHERE `id` = ?';
+ return $this->findEntity($sql, [$id]);
+ }
+
+ /**
+ * @param int $limit
+ * @param int $offset
+ * @return Text[]
+ */
+ public function findAll($limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_txts`';
+ return $this->findEntities($sql, $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ * @param int $limit
+ * @param int $offset
+ * @return Text[]
+ */
+ public function findByPoll($pollId, $limit=null, $offset=null) {
+ $sql = 'SELECT * FROM `*PREFIX*polls_txts` WHERE poll_id=?';
+ return $this->findEntities($sql, [$pollId], $limit, $offset);
+ }
+
+ /**
+ * @param string $pollId
+ */
+ public function deleteByPoll($pollId) {
+ $sql = 'DELETE FROM `*PREFIX*polls_txts` WHERE poll_id=?';
+ $this->execute($sql, [$pollId]);
+ }
+}
diff --git a/img/app-logo-polls.svg b/img/app-logo-polls.svg
new file mode 100644
index 00000000..136e6590
--- /dev/null
+++ b/img/app-logo-polls.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ viewBox="0 0 32 32.000001"
+ id="svg4312"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="app-logo-polls.svg">
+ <defs
+ id="defs4314" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.2"
+ inkscape:cx="38.97017"
+ inkscape:cy="12.744663"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4320" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4317">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1020.3621)">
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="rect4345"
+ width="8"
+ height="28"
+ x="2"
+ y="1022.3621" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="rect4347"
+ width="8"
+ height="18"
+ x="12"
+ y="1032.3621" />
+ <rect
+ style="fill:#ffffff;fill-opacity:1;stroke:none"
+ id="rect4349"
+ width="8"
+ height="26"
+ x="22"
+ y="1024.3621" />
+ </g>
+</svg>
diff --git a/index.php b/index.php
new file mode 100644
index 00000000..275f30f7
--- /dev/null
+++ b/index.php
@@ -0,0 +1,14 @@
+<?php
+
+// Check if we are a user
+//OCP\User::checkLoggedIn();
+\OC::$server->getNavigationManager()->setActiveEntry( 'polls' );
+
+//echo '<pre>r_uri: '; print_r($_SERVER); '</pre>';
+if (OCP\User::isLoggedIn()) {
+ $tmpl = new OCP\Template('polls', 'main', 'user');
+}
+else {
+ $tmpl = new OCP\Template('polls', 'main', 'base');
+}
+$tmpl->printPage();
diff --git a/js/create_edit.js b/js/create_edit.js
new file mode 100644
index 00000000..fbe380cf
--- /dev/null
+++ b/js/create_edit.js
@@ -0,0 +1,460 @@
+var g_chosen_datetimes = [];
+var g_chosen_texts = [];
+var g_chosen_groups = [];
+var g_chosen_users = [];
+var g_tmp_groups = [];
+var g_tmp_users = [];
+var chosen_type = 'event';
+var access_type = '';
+
+$(document).ready(function () {
+ // enable / disable date picker
+ $('#id_expire_set').click(function(){
+ $('#id_expire_date').prop("disabled", !this.checked);
+
+ // TODO: this would be nice, for some reason it doesn't work
+ //if (this.checked) {
+ // $("id_expire_date").focus();
+ //}
+ });
+
+ var privateRadio = document.getElementById('private');
+ var hiddenRadio = document.getElementById('hidden');
+ var publicRadio = document.getElementById('public');
+ var selectRadio = document.getElementById('select');
+ privateRadio.onclick = hideSelectTable;
+ hiddenRadio.onclick = hideSelectTable;
+ publicRadio.onclick = hideSelectTable;
+ selectRadio.onclick = showSelectTable;
+ if(privateRadio.checked) access_type = 'registered';
+ if(hiddenRadio.checked) access_type = 'hidden';
+ if(publicRadio.checked) access_type = 'public';
+ if(selectRadio.checked) access_type = 'select';
+
+ var accessValues = document.getElementById('accessValues');
+ if(accessValues.value.length > 0) {
+ var accessValueArr = accessValues.value.split(';');
+ for(var i=0; i<accessValueArr.length; i++) {
+ var val = accessValueArr[i];
+ var index = val.indexOf('group_');
+ if(index == 0) {
+ g_chosen_groups.push(val.substring(6));
+ } else {
+ index = val.indexOf('user_');
+ if(index == 0) {
+ g_chosen_users.push(val.substring(5));
+ }
+ }
+ }
+ }
+
+ var chosenDates = document.getElementById('chosenDates').value;
+ var chosen = '';
+ if(chosenDates.length > 0) chosen = JSON.parse(chosenDates);
+ var text = document.getElementById('text');
+ var event = document.getElementById('event');
+ if(event.checked) {
+ chosen_type = event.value;
+ if(chosenDates.length > 0) g_chosen_datetimes = chosen;
+ for(var i=0; i<chosen.length; i++) {
+ var date = new Date(chosen[i]*1000);
+ var year = date.getFullYear();
+ var month = date.getMonth();
+ var day = date.getDate();
+ var newDate = new Date(year, month, day).getTime(); //save timestamp without time of day
+ month = '0' + (month+1); //month is 0-11, so +1
+ day = '0' + day;
+ var dateStr = day.substr(-2) + '.' + month.substr(-2) + '.' + year;
+ var hours = date.getHours();
+ var minutes = date.getMinutes();
+ var ms = (hours * 60 * 60 * 1000) + (minutes * 60 * 1000); //time of day in milliseconds
+ hours = '0' + hours;
+ minutes = '0' + minutes;
+ var timeStr = hours.substr(-2) + ':' + minutes.substr(-2);
+ addRowToList(newDate/1000, dateStr, ms/1000);
+ addColToList(ms/1000, timeStr, newDate/1000);
+ }
+ } else {
+ chosen_type = text.value;
+ if(chosenDates.length > 0) g_chosen_texts = chosen;
+ for(var i=0; i<chosen.length; i++) {
+ insertText(chosen[i], true);
+ }
+ }
+
+ var expirepicker = jQuery('#id_expire_date').datetimepicker({
+ inline: false,
+ onSelectDate: function(date, $i) {
+ var year = date.getFullYear();
+ var month = date.getMonth();
+ var day = date.getDate();
+ var newDate = new Date(year, month, day).getTime()/1000;
+ document.getElementById('expireTs').value = newDate;
+ },
+ timepicker: false,
+ format: 'd.m.Y'
+ });
+
+ var datepicker = jQuery('#datetimepicker').datetimepicker({
+ inline:true,
+ step: 15,
+ todayButton: true,
+ onSelectDate: function(date, $i) {
+ var year = date.getFullYear();
+ var month = date.getMonth();
+ var day = date.getDate();
+ var newDate = new Date(year, month, day).getTime(); //save timestamp without time of day
+ month = '0' + (month+1); //month is 0-11, so +1
+ day = '0' + day;
+ var dateStr = day.substr(-2) + '.' + month.substr(-2) + '.' + year;
+ addRowToList(newDate/1000, dateStr);
+ },
+ onSelectTime: function(date, $i) {
+ var hours = date.getHours();
+ var minutes = date.getMinutes();
+ var ms = (hours * 60 * 60 * 1000) + (minutes * 60 * 1000); //time of day in milliseconds
+ hours = '0' + hours;
+ minutes = '0' + minutes;
+ var timeStr = hours.substr(-2) + ':' + minutes.substr(-2);
+ addColToList(ms/1000, timeStr);
+ }
+ });
+
+ $(document).on('click', '.date-row', function(e) {
+ var tr = $(this).parent();
+ var dateId = parseInt(tr.attr('id'));
+ var index = tr.index();
+ var cells = tr[0].cells; //convert jQuery object to DOM
+ for(var i=1; i<cells.length; i++) {
+ var cell = cells[i];
+ var delIndex = g_chosen_datetimes.indexOf(dateId + parseInt(cell.id));
+ if(delIndex > -1) g_chosen_datetimes.splice(delIndex, 1);
+ }
+ var table = document.getElementById('selected-dates-table');
+ table.deleteRow(index);
+ });
+
+ $(document).on('click', '.date-col', function(e) {
+ var cellIndex = $(this).index();
+ var timeId = parseInt($(this).attr('id'));
+ var table = document.getElementById('selected-dates-table');
+ var rows = table.rows;
+ rows[0].deleteCell(cellIndex);
+ for(var i=1; i<rows.length; i++) {
+ var row = rows[i];
+ var delIndex = g_chosen_datetimes.indexOf(parseInt(row.id) + timeId);
+ if(delIndex > -1) g_chosen_datetimes.splice(delIndex, 1);
+ row.deleteCell(cellIndex);
+ }
+ });
+
+ $(document).on('click', '.text-row', function(e) {
+ var tr = $(this).parent();
+ var rowIndex = tr.index();
+ var name = $(this).html();
+ var delIndex = g_chosen_texts.indexOf(name);
+ if(delIndex > -1) g_chosen_texts.splice(index, 1);
+ var table = document.getElementById('selected-texts-table');
+ table.deleteRow(rowIndex);
+ });
+
+ $(document).on('click', '.icon-close', function(e) {
+ $(this).removeClass('icon-close');
+ $(this).addClass('icon-checkmark');
+ if($(this).attr('class').indexOf('is-text') > -1) {
+ var id = $(this).attr('id');
+ g_chosen_texts.push(id.substring(id.indexOf('_') + 1));
+ } else {
+ var dateId = $(this).parent().attr('id'); //timestamp of date
+ var timeId = $(this).attr('id');
+ g_chosen_datetimes.push(parseInt(dateId) + parseInt(timeId));
+ }
+ });
+
+ $(document).on('click', '.icon-checkmark', function(e) {
+ $(this).removeClass('icon-checkmark');
+ $(this).addClass('icon-close');
+ if($(this).attr('class').indexOf('is-text') > -1) {
+ var id = $(this).attr('id');
+ var index = g_chosen_texts.indexOf(id.substring(id.indexOf('_') + 1));
+ if(index > -1) g_chosen_texts.splice(index, 1);
+ } else {
+ var dateId = $(this).parent().attr('id'); //timestamp of date
+ var timeId = $(this).attr('id');
+ var index = g_chosen_datetimes.indexOf(parseInt(dateId) + parseInt(timeId));
+ if(index > -1) g_chosen_datetimes.splice(index, 1);
+ }
+ });
+
+ $(document).on('click', '#text-submit', function(e) {
+ var text = document.getElementById('text-title');
+ if(text.value.length == 0) {
+ alert('Please enter a text!');
+ return false;
+ }
+ insertText(text.value);
+ text.value = '';
+ });
+
+ $(document).on('click', '#button_cancel_access', function(e) {
+ g_tmp_groups = [];
+ g_tmp_users = [];
+ closeAccessDialog();
+ });
+
+ $(document).on('click', '#button_ok_access', function(e) {
+ g_chosen_groups = g_tmp_groups;
+ g_chosen_users = g_tmp_users;
+ g_tmp_groups = [];
+ g_tmp_users = [];
+ closeAccessDialog();
+ });
+
+ $(document).on('click', '.cl_user_item', function(e) {
+ $(this).switchClass('cl_user_item', 'cl_user_item_selected');
+ g_tmp_users.push(this.innerHTML);
+ });
+
+ $(document).on('click', '.cl_user_item_selected', function(e) {
+ $(this).switchClass('cl_user_item_selected', 'cl_user_item');
+ var index = g_tmp_users.indexOf(this.innerHTML);
+ if(index > -1) g_tmp_users.splice(index, 1);
+ });
+
+ $(document).on('click', '.cl_group_item', function(e) {
+ $(this).switchClass('cl_group_item', 'cl_group_item_selected');
+ g_tmp_groups.push(this.innerHTML);
+ });
+
+ $(document).on('click', '.cl_group_item_selected', function(e) {
+ $(this).switchClass('cl_group_item_selected', 'cl_group_item');
+ var index = g_tmp_groups.indexOf(this.innerHTML);
+ if(index > -1) g_tmp_groups.splice(index, 1);
+ });
+
+ $('input[type=radio][name=pollType]').change(function() {
+ if(this.value == 'event') {
+ chosen_type = 'event';
+ document.getElementById('text-select-container').style.display = 'none';
+ document.getElementById('date-select-container').style.display = 'inline';
+ } else {
+ chosen_type = 'text';
+ document.getElementById('text-select-container').style.display = 'inline';
+ document.getElementById('date-select-container').style.display = 'none';
+ }
+ });
+
+ $('input[type=radio][name=accessType]').change(function() {
+ access_type = this.value;
+ if(access_type == 'select') {
+ showAccessDialog();
+ } else {
+ closeAccessDialog();
+ }
+ });
+
+ $('input[type=checkbox][name=check_expire]').change(function() {
+ if(!$(this).is(':checked')) {
+ document.getElementById('expireTs').value = '';
+ }
+ });
+
+ var form = document.finish_poll;
+ var submit_finish_poll = document.getElementById('submit_finish_poll');
+ if (submit_finish_poll != null) {
+ submit_finish_poll.onclick = function() {
+ if (g_chosen_datetimes.length === 0 && g_chosen_texts.length == 0) {
+ alert(t('polls', 'Nothing selected!\nClick on cells to turn them green.'));
+ return false;
+ }
+ if(chosen_type == 'event') form.elements['chosenDates'].value = JSON.stringify(g_chosen_datetimes);
+ else form.elements['chosenDates'].value = JSON.stringify(g_chosen_texts);
+ var title = document.getElementById('pollTitle');
+ if (title == null || title.value.length == 0) {
+ alert(t('polls', 'You must enter at least a title for the new poll.'));
+ return false;
+ }
+
+ if(access_type == 'select') {
+ if(g_chosen_groups.length == 0 && g_chosen_users == 0) {
+ alert(t('polls', 'Please select at least one user or group!'));
+ return false;
+ }
+ form.elements['accessValues'].value = JSON.stringify({
+ groups: g_chosen_groups,
+ users: g_chosen_users
+ });
+ }
+ form.submit();
+ }
+ }
+});
+
+function insertText(text, set=false) {
+ var table = document.getElementById('selected-texts-table');
+ var tr = table.insertRow(-1);
+ var td = tr.insertCell(-1);
+ td.innerHTML = text;
+ td.className = 'text-row';
+ td = tr.insertCell(-1);
+ if(set) td.className = 'icon-checkmark is-text';
+ else td.className = 'icon-close is-text';
+ td.id = 'text_' + text;
+}
+
+function addRowToList(ts, text, timeTs=-1) {
+ var table = document.getElementById('selected-dates-table');
+ var rows = table.rows;
+ if(rows.length == 0) {
+ var tr = table.insertRow(-1); //start new header
+ tr.insertCell(-1);
+ tr = table.insertRow(-1); //append new row
+ tr.id = ts;
+ var td = tr.insertCell(-1);
+ td.className = 'date-row';
+ td.innerHTML = text;
+ return;
+ }
+ var curr;
+ for(var i=1; i<rows.length; i++) {
+ curr = rows[i];
+ if(curr.id == ts) return; //already in table, cancel
+ if(curr.id > ts) {
+ var tr = table.insertRow(i); //insert row at current index
+ tr.id = ts;
+ var td = tr.insertCell(-1);
+ td.className = 'date-row';
+ td.innerHTML = text;
+ for(var j=1; j<rows[0].cells.length; j++) {
+ var tdId = rows[0].cells[j].id;
+ var td = tr.insertCell(-1);
+ if(timeTs == tdId) td.className = 'icon-checkmark';
+ else td.className = 'icon-close';
+ td.id = tdId;
+ td.innerHTML = '';
+ }
+ return;
+ }
+ }
+ var tr = table.insertRow(-1); //highest value, append new row
+ tr.id = ts;
+ var td = tr.insertCell(-1);
+ td.className = 'date-row';
+ td.innerHTML = text;
+ for(var j=1; j<rows[0].cells.length; j++) {
+ var tdId = rows[0].cells[j].id;
+ var td = tr.insertCell(-1);
+ if(timeTs == tdId) td.className = 'icon-checkmark';
+ else td.className = 'icon-close';
+ td.id = tdId;
+ td.innerHTML = '';
+ }
+ return;
+}
+
+function addColToList(ts, text, dateTs=-1) {
+ var table = document.getElementById('selected-dates-table');
+ var rows = table.rows;
+ if(rows.length == 0) {
+ var tr = table.insertRow(-1);
+ tr.insertCell(-1);
+ }
+ rows = table.rows;
+
+ var tmpRow = rows[0];
+ var index = -1;
+ var found = false;
+ for(var i=0; i<tmpRow.cells.length; i++) {
+ var curr = tmpRow.cells[i];
+ if(curr.id == ts) return; //already in table, cancel
+ if(curr.id > ts) {
+ index = i;
+ break;
+ }
+ }
+
+ for(var i=0; i<rows.length; i++) {
+ var row = rows[i];
+ var cells = row.cells;
+ var td = row.insertCell(index);
+ //only display time in header row
+ if(i==0) {
+ td.innerHTML = text;
+ td.className = 'date-col';
+ } else {
+ td.innerHTML = '';
+ if(row.id == dateTs) td.className = 'icon-checkmark';
+ else td.className = 'icon-close';
+ }
+ td.id = ts;
+ }
+}
+
+//Popup dialog
+function showAccessDialog() {
+ var message = t('polls', 'Please choose the groups or users you want to add to your poll.');
+
+ // get the screen height and width
+ var maskHeight = $(document).height();
+ var maskWidth = $(window).width();
+
+ // calculate the values for center alignment
+ //var dialogTop = (maskHeight / 3) - ($('#dialog-box').height());
+ // todo: height doesn't work
+ var dialogTop = 100;
+ var dialogLeft = (maskWidth / 2) - ($('#dialog-box').width() / 2);
+
+ // assign values to the overlay and dialog box
+ $('#dialog-overlay').css({height: maskHeight, width: maskWidth}).show();
+ $('#dialog-box').css({top: dialogTop, left: dialogLeft}).show();
+
+ // display the message
+ $('#dialog-message').html(message);
+
+ var unselectedGrps = [].slice.call(document.getElementsByClassName('cl_group_item'));
+ var selectedGrps = [].slice.call(document.getElementsByClassName('cl_group_item_selected'));
+ var unselectedUsers = [].slice.call(document.getElementsByClassName('cl_user_item'));
+ var selectedUsers = [].slice.call(document.getElementsByClassName('cl_user_item_selected'));
+ cells_grp = unselectedGrps.concat(selectedGrps);
+ cells_usr = unselectedUsers.concat(selectedUsers);
+
+ var tmpGroups = g_chosen_groups.slice();
+ for(var i=0; i<cells_grp.length; i++) {
+ var curr = cells_grp[i];
+ curr.className = 'cl_group_item';
+ for(var j=0; j<tmpGroups.length; j++) {
+ if(tmpGroups[j] == curr.innerHTML) {
+ curr.className = 'cl_group_item_selected';
+ tmpGroups.splice(j, 1);
+ break;
+ }
+ }
+ }
+ var tmpUsers = g_chosen_users.slice();
+ for(var i=0; i<cells_usr.length; i++) {
+ var curr = cells_usr[i];
+ curr.className = 'cl_user_item';
+ for(var j=0; j<tmpUsers.length; j++) {
+ if(tmpUsers[j] == curr.innerHTML) {
+ curr.className = 'cl_user_item_selected';
+ tmpUsers.splice(j, 1);
+ break;
+ }
+ }
+ }
+ g_tmp_groups = g_chosen_groups.slice();
+ g_tmp_users = g_chosen_users.slice();
+}
+
+function closeAccessDialog() {
+ $('#dialog-box').hide();
+ return false;
+}
+
+function showSelectTable() {
+ document.getElementById("table_access").style.display = "table";
+}
+
+function hideSelectTable() {
+ document.getElementById("table_access").style.display = "none";
+}
diff --git a/js/jquery.datetimepicker.full.min.js b/js/jquery.datetimepicker.full.min.js
new file mode 100644
index 00000000..633d0a8c
--- /dev/null
+++ b/js/jquery.datetimepicker.full.min.js
@@ -0,0 +1,2 @@
+var DateFormatter;!function(){"use strict";var e,t,a,n,r,o;r=864e5,o=3600,e=function(e,t){return"string"==typeof e&&"string"==typeof t&&e.toLowerCase()===t.toLowerCase()},t=function(e,a,n){var r=n||"0",o=e.toString();return o.length<a?t(r+o,a):o},a=function(e){var t,n;for(e=e||{},t=1;t<arguments.length;t++)if(n=arguments[t])for(var r in n)n.hasOwnProperty(r)&&("object"==typeof n[r]?a(e[r],n[r]):e[r]=n[r]);return e},n={dateSettings:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],meridiem:["AM","PM"],ordinal:function(e){var t=e%10,a={1:"st",2:"nd",3:"rd"};return 1!==Math.floor(e%100/10)&&a[t]?a[t]:"th"}},separators:/[ \-+\/\.T:@]/g,validParts:/[dDjlNSwzWFmMntLoYyaABgGhHisueTIOPZcrU]/g,intParts:/[djwNzmnyYhHgGis]/g,tzParts:/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,tzClip:/[^-+\dA-Z]/g},DateFormatter=function(e){var t=this,r=a(n,e);t.dateSettings=r.dateSettings,t.separators=r.separators,t.validParts=r.validParts,t.intParts=r.intParts,t.tzParts=r.tzParts,t.tzClip=r.tzClip},DateFormatter.prototype={constructor:DateFormatter,parseDate:function(t,a){var n,r,o,i,s,d,u,l,f,c,h=this,m=!1,g=!1,p=h.dateSettings,y={date:null,year:null,month:null,day:null,hour:0,min:0,sec:0};if(!t)return void 0;if(t instanceof Date)return t;if("number"==typeof t)return new Date(t);if("U"===a)return o=parseInt(t),o?new Date(1e3*o):t;if("string"!=typeof t)return"";if(n=a.match(h.validParts),!n||0===n.length)throw new Error("Invalid date format definition.");for(r=t.replace(h.separators,"\x00").split("\x00"),o=0;o<r.length;o++)switch(i=r[o],s=parseInt(i),n[o]){case"y":case"Y":f=i.length,2===f?y.year=parseInt((70>s?"20":"19")+i):4===f&&(y.year=s),m=!0;break;case"m":case"n":case"M":case"F":isNaN(i)?(d=p.monthsShort.indexOf(i),d>-1&&(y.month=d+1),d=p.months.indexOf(i),d>-1&&(y.month=d+1)):s>=1&&12>=s&&(y.month=s),m=!0;break;case"d":case"j":s>=1&&31>=s&&(y.day=s),m=!0;break;case"g":case"h":u=n.indexOf("a")>-1?n.indexOf("a"):n.indexOf("A")>-1?n.indexOf("A"):-1,c=r[u],u>-1?(l=e(c,p.meridiem[0])?0:e(c,p.meridiem[1])?12:-1,s>=1&&12>=s&&l>-1?y.hour=s+l-1:s>=0&&23>=s&&(y.hour=s)):s>=0&&23>=s&&(y.hour=s),g=!0;break;case"G":case"H":s>=0&&23>=s&&(y.hour=s),g=!0;break;case"i":s>=0&&59>=s&&(y.min=s),g=!0;break;case"s":s>=0&&59>=s&&(y.sec=s),g=!0}if(m===!0&&y.year&&y.month&&y.day)y.date=new Date(y.year,y.month-1,y.day,y.hour,y.min,y.sec,0);else{if(g!==!0)return!1;y.date=new Date(0,0,0,y.hour,y.min,y.sec,0)}return y.date},guessDate:function(e,t){if("string"!=typeof e)return e;var a,n,r,o,i=this,s=e.replace(i.separators,"\x00").split("\x00"),d=/^[djmn]/g,u=t.match(i.validParts),l=new Date,f=0;if(!d.test(u[0]))return e;for(n=0;n<s.length;n++){switch(f=2,r=s[n],o=parseInt(r.substr(0,2)),n){case 0:"m"===u[0]||"n"===u[0]?l.setMonth(o-1):l.setDate(o);break;case 1:"m"===u[0]||"n"===u[0]?l.setDate(o):l.setMonth(o-1);break;case 2:a=l.getFullYear(),r.length<4?(l.setFullYear(parseInt(a.toString().substr(0,4-r.length)+r)),f=r.length):(l.setFullYear=parseInt(r.substr(0,4)),f=4);break;case 3:l.setHours(o);break;case 4:l.setMinutes(o);break;case 5:l.setSeconds(o)}r.substr(f).length>0&&s.splice(n+1,0,r.substr(f))}return l},parseFormat:function(e,a){var n,i=this,s=i.dateSettings,d=/\\?(.?)/gi,u=function(e,t){return n[e]?n[e]():t};return n={d:function(){return t(n.j(),2)},D:function(){return s.daysShort[n.w()]},j:function(){return a.getDate()},l:function(){return s.days[n.w()]},N:function(){return n.w()||7},w:function(){return a.getDay()},z:function(){var e=new Date(n.Y(),n.n()-1,n.j()),t=new Date(n.Y(),0,1);return Math.round((e-t)/r)},W:function(){var e=new Date(n.Y(),n.n()-1,n.j()-n.N()+3),a=new Date(e.getFullYear(),0,4);return t(1+Math.round((e-a)/r/7),2)},F:function(){return s.months[a.getMonth()]},m:function(){return t(n.n(),2)},M:function(){return s.monthsShort[a.getMonth()]},n:function(){return a.getMonth()+1},t:function(){return new Date(n.Y(),n.n(),0).getDate()},L:function(){var e=n.Y();return e%4===0&&e%100!==0||e%400===0?1:0},o:function(){var e=n.n(),t=n.W(),a=n.Y();return a+(12===e&&9>t?1:1===e&&t>9?-1:0)},Y:function(){return a.getFullYear()},y:function(){return n.Y().toString().slice(-2)},a:function(){return n.A().toLowerCase()},A:function(){var e=n.G()<12?0:1;return s.meridiem[e]},B:function(){var e=a.getUTCHours()*o,n=60*a.getUTCMinutes(),r=a.getUTCSeconds();return t(Math.floor((e+n+r+o)/86.4)%1e3,3)},g:function(){return n.G()%12||12},G:function(){return a.getHours()},h:function(){return t(n.g(),2)},H:function(){return t(n.G(),2)},i:function(){return t(a.getMinutes(),2)},s:function(){return t(a.getSeconds(),2)},u:function(){return t(1e3*a.getMilliseconds(),6)},e:function(){var e=/\((.*)\)/.exec(String(a))[1];return e||"Coordinated Universal Time"},T:function(){var e=(String(a).match(i.tzParts)||[""]).pop().replace(i.tzClip,"");return e||"UTC"},I:function(){var e=new Date(n.Y(),0),t=Date.UTC(n.Y(),0),a=new Date(n.Y(),6),r=Date.UTC(n.Y(),6);return e-t!==a-r?1:0},O:function(){var e=a.getTimezoneOffset(),n=Math.abs(e);return(e>0?"-":"+")+t(100*Math.floor(n/60)+n%60,4)},P:function(){var e=n.O();return e.substr(0,3)+":"+e.substr(3,2)},Z:function(){return 60*-a.getTimezoneOffset()},c:function(){return"Y-m-d\\TH:i:sP".replace(d,u)},r:function(){return"D, d M Y H:i:s O".replace(d,u)},U:function(){return a.getTime()/1e3||0}},u(e,e)},formatDate:function(e,t){var a,n,r,o,i,s=this,d="";if("string"==typeof e&&(e=s.parseDate(e,t),e===!1))return!1;if(e instanceof Date){for(r=t.length,a=0;r>a;a++)i=t.charAt(a),"S"!==i&&(o=s.parseFormat(i,e),a!==r-1&&s.intParts.test(i)&&"S"===t.charAt(a+1)&&(n=parseInt(o),o+=s.dateSettings.ordinal(n)),d+=o);return d}return""}}}(),function(e){"function"==typeof define&&define.amd?define(["jquery","jquery-mousewheel","date-functions"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(e){"use strict";function t(e,t,a){this.date=e,this.desc=t,this.style=a}var a={i18n:{ar:{months:["كانون الثاني","شباط","آذار","نيسان","مايو","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],dayOfWeekShort:["ن","ث","ع","خ","ج","س","ح"],dayOfWeek:["الأحد","الاثنين","الثلاثاء","الأربعاء","الخميس","الجمعة","السبت","الأحد"]},ro:{months:["Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie","Iulie","August","Septembrie","Octombrie","Noiembrie","Decembrie"],dayOfWeekShort:["Du","Lu","Ma","Mi","Jo","Vi","Sâ"],dayOfWeek:["Duminică","Luni","Marţi","Miercuri","Joi","Vineri","Sâmbătă"]},id:{months:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],dayOfWeekShort:["Min","Sen","Sel","Rab","Kam","Jum","Sab"],dayOfWeek:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"]},is:{months:["Janúar","Febrúar","Mars","Apríl","Maí","Júní","Júlí","Ágúst","September","Október","Nóvember","Desember"],dayOfWeekShort:["Sun","Mán","Þrið","Mið","Fim","Fös","Lau"],dayOfWeek:["Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur"]},bg:{months:["Януари","Февруари","Март","Април","Май","Юни","Юли","Август","Септември","Октомври","Ноември","Декември"],dayOfWeekShort:["Нд","Пн","Вт","Ср","Чт","Пт","Сб"],dayOfWeek:["Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота"]},fa:{months:["فروردین","اردیبهشت","خرداد","تیر","مرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"],dayOfWeekShort:["یکشنبه","دوشنبه","سه شنبه","چهارشنبه","پنجشنبه","جمعه","شنبه"],dayOfWeek:["یک‌شنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه","یک‌شنبه"]},ru:{months:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],dayOfWeekShort:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],dayOfWeek:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"]},uk:{months:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],dayOfWeekShort:["Ндл","Пнд","Втр","Срд","Чтв","Птн","Сбт"],dayOfWeek:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"]},en:{months:["January","February","March","April","May","June","July","August","September","October","November","December"],dayOfWeekShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayOfWeek:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},el:{months:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],dayOfWeekShort:["Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ"],dayOfWeek:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο"]},de:{months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],dayOfWeekShort:["So","Mo","Di","Mi","Do","Fr","Sa"],dayOfWeek:["Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag"]},nl:{months:["januari","februari","maart","april","mei","juni","juli","augustus","september","oktober","november","december"],dayOfWeekShort:["zo","ma","di","wo","do","vr","za"],dayOfWeek:["zondag","maandag","dinsdag","woensdag","donderdag","vrijdag","zaterdag"]},tr:{months:["Ocak","Şubat","Mart","Nisan","Mayıs","Haziran","Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık"],dayOfWeekShort:["Paz","Pts","Sal","Çar","Per","Cum","Cts"],dayOfWeek:["Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi"]},fr:{months:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],dayOfWeekShort:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],dayOfWeek:["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"]},es:{months:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],dayOfWeekShort:["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"],dayOfWeek:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"]},th:{months:["มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม"],dayOfWeekShort:["อา.","จ.","อ.","พ.","พฤ.","ศ.","ส."],dayOfWeek:["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัส","ศุกร์","เสาร์","อาทิตย์"]},pl:{months:["styczeń","luty","marzec","kwiecień","maj","czerwiec","lipiec","sierpień","wrzesień","październik","listopad","grudzień"],dayOfWeekShort:["nd","pn","wt","śr","cz","pt","sb"],dayOfWeek:["niedziela","poniedziałek","wtorek","środa","czwartek","piątek","sobota"]},pt:{months:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],dayOfWeekShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sab"],dayOfWeek:["Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado"]},ch:{months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayOfWeekShort:["日","一","二","三","四","五","六"]},se:{months:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],dayOfWeekShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"]},kr:{months:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],dayOfWeekShort:["일","월","화","수","목","금","토"],dayOfWeek:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"]},it:{months:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],dayOfWeekShort:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],dayOfWeek:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"]},da:{months:["January","Februar","Marts","April","Maj","Juni","July","August","September","Oktober","November","December"],dayOfWeekShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayOfWeek:["søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag"]},no:{months:["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],dayOfWeekShort:["Søn","Man","Tir","Ons","Tor","Fre","Lør"],dayOfWeek:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"]},ja:{months:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayOfWeekShort:["日","月","火","水","木","金","土"],dayOfWeek:["日曜","月曜","火曜","水曜","木曜","金曜","土曜"]},vi:{months:["Tháng 1","Tháng 2","Tháng 3","Tháng 4","Tháng 5","Tháng 6","Tháng 7","Tháng 8","Tháng 9","Tháng 10","Tháng 11","Tháng 12"],dayOfWeekShort:["CN","T2","T3","T4","T5","T6","T7"],dayOfWeek:["Chủ nhật","Thứ hai","Thứ ba","Thứ tư","Thứ năm","Thứ sáu","Thứ bảy"]},sl:{months:["Januar","Februar","Marec","April","Maj","Junij","Julij","Avgust","September","Oktober","November","December"],dayOfWeekShort:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"],dayOfWeek:["Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota"]},cs:{months:["Leden","Únor","Březen","Duben","Květen","Červen","Červenec","Srpen","Září","Říjen","Listopad","Prosinec"],dayOfWeekShort:["Ne","Po","Út","St","Čt","Pá","So"]},hu:{months:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],dayOfWeekShort:["Va","Hé","Ke","Sze","Cs","Pé","Szo"],dayOfWeek:["vasárnap","hétfő","kedd","szerda","csütörtök","péntek","szombat"]},az:{months:["Yanvar","Fevral","Mart","Aprel","May","Iyun","Iyul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr"],dayOfWeekShort:["B","Be","Ça","Ç","Ca","C","Ş"],dayOfWeek:["Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə"]},bs:{months:["Januar","Februar","Mart","April","Maj","Jun","Jul","Avgust","Septembar","Oktobar","Novembar","Decembar"],dayOfWeekShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayOfWeek:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"]},ca:{months:["Gener","Febrer","Març","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],dayOfWeekShort:["Dg","Dl","Dt","Dc","Dj","Dv","Ds"],dayOfWeek:["Diumenge","Dilluns","Dimarts","Dimecres","Dijous","Divendres","Dissabte"]},"en-GB":{months:["January","February","March","April","May","June","July","August","September","October","November","December"],dayOfWeekShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayOfWeek:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},et:{months:["Jaanuar","Veebruar","Märts","Aprill","Mai","Juuni","Juuli","August","September","Oktoober","November","Detsember"],dayOfWeekShort:["P","E","T","K","N","R","L"],dayOfWeek:["Pühapäev","Esmaspäev","Teisipäev","Kolmapäev","Neljapäev","Reede","Laupäev"]},eu:{months:["Urtarrila","Otsaila","Martxoa","Apirila","Maiatza","Ekaina","Uztaila","Abuztua","Iraila","Urria","Azaroa","Abendua"],dayOfWeekShort:["Ig.","Al.","Ar.","Az.","Og.","Or.","La."],dayOfWeek:["Igandea","Astelehena","Asteartea","Asteazkena","Osteguna","Ostirala","Larunbata"]},fi:{months:["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],dayOfWeekShort:["Su","Ma","Ti","Ke","To","Pe","La"],dayOfWeek:["sunnuntai","maanantai","tiistai","keskiviikko","torstai","perjantai","lauantai"]},gl:{months:["Xan","Feb","Maz","Abr","Mai","Xun","Xul","Ago","Set","Out","Nov","Dec"],dayOfWeekShort:["Dom","Lun","Mar","Mer","Xov","Ven","Sab"],dayOfWeek:["Domingo","Luns","Martes","Mércores","Xoves","Venres","Sábado"]},hr:{months:["Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj","Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac"],dayOfWeekShort:["Ned","Pon","Uto","Sri","Čet","Pet","Sub"],dayOfWeek:["Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota"]},ko:{months:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],dayOfWeekShort:["일","월","화","수","목","금","토"],dayOfWeek:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"]},lt:{months:["Sausio","Vasario","Kovo","Balandžio","Gegužės","Birželio","Liepos","Rugpjūčio","Rugsėjo","Spalio","Lapkričio","Gruodžio"],dayOfWeekShort:["Sek","Pir","Ant","Tre","Ket","Pen","Šeš"],dayOfWeek:["Sekmadienis","Pirmadienis","Antradienis","Trečiadienis","Ketvirtadienis","Penktadienis","Šeštadienis"]},lv:{months:["Janvāris","Februāris","Marts","Aprīlis ","Maijs","Jūnijs","Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris"],dayOfWeekShort:["Sv","Pr","Ot","Tr","Ct","Pk","St"],dayOfWeek:["Svētdiena","Pirmdiena","Otrdiena","Trešdiena","Ceturtdiena","Piektdiena","Sestdiena"]},mk:{months:["јануари","февруари","март","април","мај","јуни","јули","август","септември","октомври","ноември","декември"],dayOfWeekShort:["нед","пон","вто","сре","чет","пет","саб"],dayOfWeek:["Недела","Понеделник","Вторник","Среда","Четврток","Петок","Сабота"]},mn:{months:["1-р сар","2-р сар","3-р сар","4-р сар","5-р сар","6-р сар","7-р сар","8-р сар","9-р сар","10-р сар","11-р сар","12-р сар"],dayOfWeekShort:["Дав","Мяг","Лха","Пүр","Бсн","Бям","Ням"],dayOfWeek:["Даваа","Мягмар","Лхагва","Пүрэв","Баасан","Бямба","Ням"]},"pt-BR":{months:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],dayOfWeekShort:["Dom","Seg","Ter","Qua","Qui","Sex","Sáb"],dayOfWeek:["Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado"]},sk:{months:["Január","Február","Marec","Apríl","Máj","Jún","Júl","August","September","Október","November","December"],dayOfWeekShort:["Ne","Po","Ut","St","Št","Pi","So"],dayOfWeek:["Nedeľa","Pondelok","Utorok","Streda","Štvrtok","Piatok","Sobota"]},sq:{months:["Janar","Shkurt","Mars","Prill","Maj","Qershor","Korrik","Gusht","Shtator","Tetor","Nëntor","Dhjetor"],dayOfWeekShort:["Die","Hën","Mar","Mër","Enj","Pre","Shtu"],dayOfWeek:["E Diel","E Hënë","E Martē","E Mërkurë","E Enjte","E Premte","E Shtunë"]},"sr-YU":{months:["Januar","Februar","Mart","April","Maj","Jun","Jul","Avgust","Septembar","Oktobar","Novembar","Decembar"],dayOfWeekShort:["Ned","Pon","Uto","Sre","čet","Pet","Sub"],dayOfWeek:["Nedelja","Ponedeljak","Utorak","Sreda","Četvrtak","Petak","Subota"]},sr:{months:["јануар","фебруар","март","април","мај","јун","јул","август","септембар","октобар","новембар","децембар"],dayOfWeekShort:["нед","пон","уто","сре","чет","пет","суб"],dayOfWeek:["Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота"]},sv:{months:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],dayOfWeekShort:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"],dayOfWeek:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"]},"zh-TW":{months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayOfWeekShort:["日","一","二","三","四","五","六"],dayOfWeek:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]},zh:{months:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],dayOfWeekShort:["日","一","二","三","四","五","六"],dayOfWeek:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]},he:{months:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],dayOfWeekShort:["א'","ב'","ג'","ד'","ה'","ו'","שבת"],dayOfWeek:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת","ראשון"]},hy:{months:["Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս","Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր"],dayOfWeekShort:["Կի","Երկ","Երք","Չոր","Հնգ","Ուրբ","Շբթ"],dayOfWeek:["Կիրակի","Երկուշաբթի","Երեքշաբթի","Չորեքշաբթի","Հինգշաբթի","Ուրբաթ","Շաբաթ"]},kg:{months:["Үчтүн айы","Бирдин айы","Жалган Куран","Чын Куран","Бугу","Кулжа","Теке","Баш Оона","Аяк Оона","Тогуздун айы","Жетинин айы","Бештин айы"],dayOfWeekShort:["Жек","Дүй","Шей","Шар","Бей","Жум","Ише"],dayOfWeek:["Жекшемб","Дүйшөмб","Шейшемб","Шаршемб","Бейшемби","Жума","Ишенб"]},rm:{months:["Schaner","Favrer","Mars","Avrigl","Matg","Zercladur","Fanadur","Avust","Settember","October","November","December"],dayOfWeekShort:["Du","Gli","Ma","Me","Gie","Ve","So"],dayOfWeek:["Dumengia","Glindesdi","Mardi","Mesemna","Gievgia","Venderdi","Sonda"]}},value:"",rtl:!1,format:"Y/m/d H:i",formatTime:"H:i",formatDate:"Y/m/d",startDate:!1,step:60,monthChangeSpinner:!0,closeOnDateSelect:!1,closeOnTimeSelect:!0,closeOnWithoutClick:!0,closeOnInputClick:!0,timepicker:!0,datepicker:!0,weeks:!1,defaultTime:!1,defaultDate:!1,minDate:!1,maxDate:!1,minTime:!1,maxTime:!1,disabledMinTime:!1,disabledMaxTime:!1,allowTimes:[],opened:!1,initTime:!0,inline:!1,theme:"",onSelectDate:function(){},onSelectTime:function(){},onChangeMonth:function(){},onChangeYear:function(){},onChangeDateTime:function(){},onShow:function(){},onClose:function(){},onGenerate:function(){},withoutCopyright:!0,inverseButton:!1,hours12:!1,next:"xdsoft_next",prev:"xdsoft_prev",dayOfWeekStart:0,parentID:"body",timeHeightInTimePicker:25,timepickerScrollbar:!0,todayButton:!0,prevButton:!0,nextButton:!0,defaultSelect:!0,scrollMonth:!0,scrollTime:!0,scrollInput:!0,lazyInit:!1,mask:!1,validateOnBlur:!0,allowBlank:!0,yearStart:1950,yearEnd:2050,monthStart:0,monthEnd:11,style:"",id:"",fixed:!1,roundTime:"round",className:"",weekends:[],highlightedDates:[],highlightedPeriods:[],disabledDates:[],disabledWeekDays:[],yearOffset:0,beforeShowDay:null,enterLikeTab:!0,showApplyButton:!1},n=null,r="en",o="en",i={meridiem:["AM","PM"]},s=function(){var t=a.i18n[o],r={days:t.dayOfWeek,daysShort:t.dayOfWeekShort,months:t.months,monthsShort:e.map(t.months,function(e){return e.substring(0,3)})};n=new DateFormatter({dateSettings:e.extend({},i,r)})};e.datetimepicker={setLocale:function(e){var t=a.i18n[e]?e:r;o!=t&&(o=t,s())},RFC_2822:"D, d M Y H:i:s O",ATOM:"Y-m-dTH:i:sP",ISO_8601:"Y-m-dTH:i:sO",RFC_822:"D, d M y H:i:s O",RFC_850:"l, d-M-y H:i:s T",RFC_1036:"D, d M y H:i:s O",RFC_1123:"D, d M Y H:i:s O",RSS:"D, d M Y H:i:s O",W3C:"Y-m-dTH:i:sP"},s(),window.getComputedStyle||(window.getComputedStyle=function(e){return this.el=e,this.getPropertyValue=function(t){var a=/(\-([a-z]){1})/g;return"float"===t&&(t="styleFloat"),a.test(t)&&(t=t.replace(a,function(e,t,a){return a.toUpperCase()})),e.currentStyle[t]||null},this}),Array.prototype.indexOf||(Array.prototype.indexOf=function(e,t){var a,n;for(a=t||0,n=this.length;n>a;a+=1)if(this[a]===e)return a;return-1}),Date.prototype.countDaysInMonth=function(){return new Date(this.getFullYear(),this.getMonth()+1,0).getDate()},e.fn.xdsoftScroller=function(t){return this.each(function(){var a,n,r,o,i,s=e(this),d=function(e){var t,a={x:0,y:0};return"touchstart"===e.type||"touchmove"===e.type||"touchend"===e.type||"touchcancel"===e.type?(t=e.originalEvent.touches[0]||e.originalEvent.changedTouches[0],a.x=t.clientX,a.y=t.clientY):("mousedown"===e.type||"mouseup"===e.type||"mousemove"===e.type||"mouseover"===e.type||"mouseout"===e.type||"mouseenter"===e.type||"mouseleave"===e.type)&&(a.x=e.clientX,a.y=e.clientY),a},u=100,l=!1,f=0,c=0,h=0,m=!1,g=0,p=function(){};return"hide"===t?void s.find(".xdsoft_scrollbar").hide():(e(this).hasClass("xdsoft_scroller_box")||(a=s.children().eq(0),n=s[0].clientHeight,r=a[0].offsetHeight,o=e('<div class="xdsoft_scrollbar"></div>'),i=e('<div class="xdsoft_scroller"></div>'),o.append(i),s.addClass("xdsoft_scroller_box").append(o),p=function(e){var t=d(e).y-f+g;0>t&&(t=0),t+i[0].offsetHeight>h&&(t=h-i[0].offsetHeight),s.trigger("scroll_element.xdsoft_scroller",[u?t/u:0])},i.on("touchstart.xdsoft_scroller mousedown.xdsoft_scroller",function(a){n||s.trigger("resize_scroll.xdsoft_scroller",[t]),f=d(a).y,g=parseInt(i.css("margin-top"),10),h=o[0].offsetHeight,"mousedown"===a.type||"touchstart"===a.type?(document&&e(document.body).addClass("xdsoft_noselect"),e([document.body,window]).on("touchend mouseup.xdsoft_scroller",function r(){e([document.body,window]).off("touchend mouseup.xdsoft_scroller",r).off("mousemove.xdsoft_scroller",p).removeClass("xdsoft_noselect")}),e(document.body).on("mousemove.xdsoft_scroller",p)):(m=!0,a.stopPropagation(),a.preventDefault())}).on("touchmove",function(e){m&&(e.preventDefault(),p(e))}).on("touchend touchcancel",function(){m=!1,g=0}),s.on("scroll_element.xdsoft_scroller",function(e,t){n||s.trigger("resize_scroll.xdsoft_scroller",[t,!0]),t=t>1?1:0>t||isNaN(t)?0:t,i.css("margin-top",u*t),setTimeout(function(){a.css("marginTop",-parseInt((a[0].offsetHeight-n)*t,10))},10)}).on("resize_scroll.xdsoft_scroller",function(e,t,d){var l,f;n=s[0].clientHeight,r=a[0].offsetHeight,l=n/r,f=l*o[0].offsetHeight,l>1?i.hide():(i.show(),i.css("height",parseInt(f>10?f:10,10)),u=o[0].offsetHeight-i[0].offsetHeight,d!==!0&&s.trigger("scroll_element.xdsoft_scroller",[t||Math.abs(parseInt(a.css("marginTop"),10))/(r-n)]))}),s.on("mousewheel",function(e){var t=Math.abs(parseInt(a.css("marginTop"),10));return t-=20*e.deltaY,0>t&&(t=0),s.trigger("scroll_element.xdsoft_scroller",[t/(r-n)]),e.stopPropagation(),!1}),s.on("touchstart",function(e){l=d(e),c=Math.abs(parseInt(a.css("marginTop"),10))}),s.on("touchmove",function(e){if(l){e.preventDefault();var t=d(e);s.trigger("scroll_element.xdsoft_scroller",[(c-(t.y-l.y))/(r-n)])}}),s.on("touchend touchcancel",function(){l=!1,c=0})),void s.trigger("resize_scroll.xdsoft_scroller",[t]))})},e.fn.datetimepicker=function(r){var i,s,d=48,u=57,l=96,f=105,c=17,h=46,m=13,g=27,p=8,y=37,v=38,b=39,k=40,x=9,D=116,T=65,S=67,w=86,M=90,O=89,_=!1,W=e.isPlainObject(r)||!r?e.extend(!0,{},a,r):e.extend(!0,{},a),C=0,F=function(e){e.on("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",function t(){e.is(":disabled")||e.data("xdsoft_datetimepicker")||(clearTimeout(C),C=setTimeout(function(){e.data("xdsoft_datetimepicker")||i(e),e.off("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",t).trigger("open.xdsoft")},100))})};return i=function(a){function i(){var e,t=!1;return W.startDate?t=Y.strToDate(W.startDate):(t=W.value||(a&&a.val&&a.val()?a.val():""),t?t=Y.strToDateTime(t):W.defaultDate&&(t=Y.strToDateTime(W.defaultDate),W.defaultTime&&(e=Y.strtotime(W.defaultTime),t.setHours(e.getHours()),t.setMinutes(e.getMinutes())))),t&&Y.isValidDate(t)?j.data("changed",!0):t="",t||0}var s,C,F,P,A,Y,j=e('<div class="xdsoft_datetimepicker xdsoft_noselect"></div>'),H=e('<div class="xdsoft_copyright"><a target="_blank" href="http://xdsoft.net/jqplugins/datetimepicker/">xdsoft.net</a></div>'),J=e('<div class="xdsoft_datepicker active"></div>'),z=e('<div class="xdsoft_mounthpicker"><button type="button" class="xdsoft_prev"></button><button type="button" class="xdsoft_today_button"></button><div class="xdsoft_label xdsoft_month"><span></span><i></i></div><div class="xdsoft_label xdsoft_year"><span></span><i></i></div><button type="button" class="xdsoft_next"></button></div>'),I=e('<div class="xdsoft_calendar"></div>'),N=e('<div class="xdsoft_timepicker active"><button type="button" class="xdsoft_prev"></button><div class="xdsoft_time_box"></div><button type="button" class="xdsoft_next"></button></div>'),L=N.find(".xdsoft_time_box").eq(0),E=e('<div class="xdsoft_time_variant"></div>'),B=e('<button type="button" class="xdsoft_save_selected blue-gradient-button">Save Selected</button>'),V=e('<div class="xdsoft_select xdsoft_monthselect"><div></div></div>'),G=e('<div class="xdsoft_select xdsoft_yearselect"><div></div></div>'),R=!1,U=0,q=0;W.id&&j.attr("id",W.id),W.style&&j.attr("style",W.style),W.weeks&&j.addClass("xdsoft_showweeks"),W.rtl&&j.addClass("xdsoft_rtl"),j.addClass("xdsoft_"+W.theme),j.addClass(W.className),z.find(".xdsoft_month span").after(V),z.find(".xdsoft_year span").after(G),z.find(".xdsoft_month,.xdsoft_year").on("touchstart mousedown.xdsoft",function(t){var a,n,r=e(this).find(".xdsoft_select").eq(0),o=0,i=0,s=r.is(":visible");for(z.find(".xdsoft_select").hide(),Y.currentTime&&(o=Y.currentTime[e(this).hasClass("xdsoft_month")?"getMonth":"getFullYear"]()),r[s?"hide":"show"](),a=r.find("div.xdsoft_option"),n=0;n<a.length&&a.eq(n).data("value")!==o;n+=1)i+=a[0].offsetHeight;return r.xdsoftScroller(i/(r.children()[0].offsetHeight-r[0].clientHeight)),t.stopPropagation(),!1}),z.find(".xdsoft_select").xdsoftScroller().on("touchstart mousedown.xdsoft",function(e){e.stopPropagation(),e.preventDefault()}).on("touchstart mousedown.xdsoft",".xdsoft_option",function(){(void 0===Y.currentTime||null===Y.currentTime)&&(Y.currentTime=Y.now());var t=Y.currentTime.getFullYear();Y&&Y.currentTime&&Y.currentTime[e(this).parent().parent().hasClass("xdsoft_monthselect")?"setMonth":"setFullYear"](e(this).data("value")),e(this).parent().parent().hide(),j.trigger("xchange.xdsoft"),W.onChangeMonth&&e.isFunction(W.onChangeMonth)&&W.onChangeMonth.call(j,Y.currentTime,j.data("input")),t!==Y.currentTime.getFullYear()&&e.isFunction(W.onChangeYear)&&W.onChangeYear.call(j,Y.currentTime,j.data("input"))}),j.setOptions=function(r){var o={},i=function(e){try{if(document.selection&&document.selection.createRange){var t=document.selection.createRange();return t.getBookmark().charCodeAt(2)-2}if(e.setSelectionRange)return e.selectionStart}catch(a){return 0}},s=function(e,t){if(e="string"==typeof e||e instanceof String?document.getElementById(e):e,!e)return!1;if(e.createTextRange){var a=e.createTextRange();return a.collapse(!0),a.moveEnd("character",t),a.moveStart("character",t),a.select(),!0}return e.setSelectionRange?(e.setSelectionRange(t,t),!0):!1},C=function(e,t){var a=e.replace(/([\[\]\/\{\}\(\)\-\.\+]{1})/g,"\\$1").replace(/_/g,"{digit+}").replace(/([0-9]{1})/g,"{digit$1}").replace(/\{digit([0-9]{1})\}/g,"[0-$1_]{1}").replace(/\{digit[\+]\}/g,"[0-9_]{1}");return new RegExp(a).test(t)};W=e.extend(!0,{},W,r),r.allowTimes&&e.isArray(r.allowTimes)&&r.allowTimes.length&&(W.allowTimes=e.extend(!0,[],r.allowTimes)),r.weekends&&e.isArray(r.weekends)&&r.weekends.length&&(W.weekends=e.extend(!0,[],r.weekends)),r.highlightedDates&&e.isArray(r.highlightedDates)&&r.highlightedDates.length&&(e.each(r.highlightedDates,function(a,r){var i,s=e.map(r.split(","),e.trim),d=new t(n.parseDate(s[0],W.formatDate),s[1],s[2]),u=n.formatDate(d.date,W.formatDate);void 0!==o[u]?(i=o[u].desc,i&&i.length&&d.desc&&d.desc.length&&(o[u].desc=i+"\n"+d.desc)):o[u]=d}),W.highlightedDates=e.extend(!0,[],o)),r.highlightedPeriods&&e.isArray(r.highlightedPeriods)&&r.highlightedPeriods.length&&(o=e.extend(!0,[],W.highlightedDates),e.each(r.highlightedPeriods,function(a,r){var i,s,d,u,l,f,c;if(e.isArray(r))i=r[0],s=r[1],d=r[2],c=r[3];else{var h=e.map(r.split(","),e.trim);i=n.parseDate(h[0],W.formatDate),s=n.parseDate(h[1],W.formatDate),d=h[2],c=h[3]}for(;s>=i;)u=new t(i,d,c),l=n.formatDate(i,W.formatDate),i.setDate(i.getDate()+1),void 0!==o[l]?(f=o[l].desc,f&&f.length&&u.desc&&u.desc.length&&(o[l].desc=f+"\n"+u.desc)):o[l]=u}),W.highlightedDates=e.extend(!0,[],o)),r.disabledDates&&e.isArray(r.disabledDates)&&r.disabledDates.length&&(W.disabledDates=e.extend(!0,[],r.disabledDates)),r.disabledWeekDays&&e.isArray(r.disabledWeekDays)&&r.disabledWeekDays.length&&(W.disabledWeekDays=e.extend(!0,[],r.disabledWeekDays)),!W.open&&!W.opened||W.inline||a.trigger("open.xdsoft"),W.inline&&(R=!0,j.addClass("xdsoft_inline"),a.after(j).hide()),W.inverseButton&&(W.next="xdsoft_prev",W.prev="xdsoft_next"),W.datepicker?J.addClass("active"):J.removeClass("active"),W.timepicker?N.addClass("active"):N.removeClass("active"),W.value&&(Y.setCurrentTime(W.value),a&&a.val&&a.val(Y.str)),W.dayOfWeekStart=isNaN(W.dayOfWeekStart)?0:parseInt(W.dayOfWeekStart,10)%7,W.timepickerScrollbar||L.xdsoftScroller("hide"),W.minDate&&/^[\+\-](.*)$/.test(W.minDate)&&(W.minDate=n.formatDate(Y.strToDateTime(W.minDate),W.formatDate)),W.maxDate&&/^[\+\-](.*)$/.test(W.maxDate)&&(W.maxDate=n.formatDate(Y.strToDateTime(W.maxDate),W.formatDate)),B.toggle(W.showApplyButton),z.find(".xdsoft_today_button").css("visibility",W.todayButton?"visible":"hidden"),z.find("."+W.prev).css("visibility",W.prevButton?"visible":"hidden"),z.find("."+W.next).css("visibility",W.nextButton?"visible":"hidden"),W.mask&&(a.off("keydown.xdsoft"),W.mask===!0&&(W.mask=W.format.replace(/Y/g,"9999").replace(/F/g,"9999").replace(/m/g,"19").replace(/d/g,"39").replace(/H/g,"29").replace(/i/g,"59").replace(/s/g,"59")),
+"string"===e.type(W.mask)&&(C(W.mask,a.val())||(a.val(W.mask.replace(/[0-9]/g,"_")),s(a[0],0)),a.on("keydown.xdsoft",function(t){var n,r,o=this.value,F=t.which;if(F>=d&&u>=F||F>=l&&f>=F||F===p||F===h){for(n=i(this),r=F!==p&&F!==h?String.fromCharCode(F>=l&&f>=F?F-d:F):"_",F!==p&&F!==h||!n||(n-=1,r="_");/[^0-9_]/.test(W.mask.substr(n,1))&&n<W.mask.length&&n>0;)n+=F===p||F===h?-1:1;if(o=o.substr(0,n)+r+o.substr(n+1),""===e.trim(o))o=W.mask.replace(/[0-9]/g,"_");else if(n===W.mask.length)return t.preventDefault(),!1;for(n+=F===p||F===h?0:1;/[^0-9_]/.test(W.mask.substr(n,1))&&n<W.mask.length&&n>0;)n+=F===p||F===h?-1:1;C(W.mask,o)?(this.value=o,s(this,n)):""===e.trim(o)?this.value=W.mask.replace(/[0-9]/g,"_"):a.trigger("error_input.xdsoft")}else if(-1!==[T,S,w,M,O].indexOf(F)&&_||-1!==[g,v,k,y,b,D,c,x,m].indexOf(F))return!0;return t.preventDefault(),!1}))),W.validateOnBlur&&a.off("blur.xdsoft").on("blur.xdsoft",function(){if(W.allowBlank&&!e.trim(e(this).val()).length)e(this).val(null),j.data("xdsoft_datetime").empty();else if(n.parseDate(e(this).val(),W.format))j.data("xdsoft_datetime").setCurrentTime(e(this).val());else{var t=+[e(this).val()[0],e(this).val()[1]].join(""),a=+[e(this).val()[2],e(this).val()[3]].join("");e(this).val(!W.datepicker&&W.timepicker&&t>=0&&24>t&&a>=0&&60>a?[t,a].map(function(e){return e>9?e:"0"+e}).join(":"):n.formatDate(Y.now(),W.format)),j.data("xdsoft_datetime").setCurrentTime(e(this).val())}j.trigger("changedatetime.xdsoft")}),W.dayOfWeekStartPrev=0===W.dayOfWeekStart?6:W.dayOfWeekStart-1,j.trigger("xchange.xdsoft").trigger("afterOpen.xdsoft")},j.data("options",W).on("touchstart mousedown.xdsoft",function(e){return e.stopPropagation(),e.preventDefault(),G.hide(),V.hide(),!1}),L.append(E),L.xdsoftScroller(),j.on("afterOpen.xdsoft",function(){L.xdsoftScroller()}),j.append(J).append(N),W.withoutCopyright!==!0&&j.append(H),J.append(z).append(I).append(B),e(W.parentID).append(j),s=function(){var t=this;t.now=function(e){var a,n,r=new Date;return!e&&W.defaultDate&&(a=t.strToDateTime(W.defaultDate),r.setFullYear(a.getFullYear()),r.setMonth(a.getMonth()),r.setDate(a.getDate())),W.yearOffset&&r.setFullYear(r.getFullYear()+W.yearOffset),!e&&W.defaultTime&&(n=t.strtotime(W.defaultTime),r.setHours(n.getHours()),r.setMinutes(n.getMinutes())),r},t.isValidDate=function(e){return"[object Date]"!==Object.prototype.toString.call(e)?!1:!isNaN(e.getTime())},t.setCurrentTime=function(e){t.currentTime="string"==typeof e?t.strToDateTime(e):t.isValidDate(e)?e:t.now(),j.trigger("xchange.xdsoft")},t.empty=function(){t.currentTime=null},t.getCurrentTime=function(){return t.currentTime},t.nextMonth=function(){(void 0===t.currentTime||null===t.currentTime)&&(t.currentTime=t.now());var a,n=t.currentTime.getMonth()+1;return 12===n&&(t.currentTime.setFullYear(t.currentTime.getFullYear()+1),n=0),a=t.currentTime.getFullYear(),t.currentTime.setDate(Math.min(new Date(t.currentTime.getFullYear(),n+1,0).getDate(),t.currentTime.getDate())),t.currentTime.setMonth(n),W.onChangeMonth&&e.isFunction(W.onChangeMonth)&&W.onChangeMonth.call(j,Y.currentTime,j.data("input")),a!==t.currentTime.getFullYear()&&e.isFunction(W.onChangeYear)&&W.onChangeYear.call(j,Y.currentTime,j.data("input")),j.trigger("xchange.xdsoft"),n},t.prevMonth=function(){(void 0===t.currentTime||null===t.currentTime)&&(t.currentTime=t.now());var a=t.currentTime.getMonth()-1;return-1===a&&(t.currentTime.setFullYear(t.currentTime.getFullYear()-1),a=11),t.currentTime.setDate(Math.min(new Date(t.currentTime.getFullYear(),a+1,0).getDate(),t.currentTime.getDate())),t.currentTime.setMonth(a),W.onChangeMonth&&e.isFunction(W.onChangeMonth)&&W.onChangeMonth.call(j,Y.currentTime,j.data("input")),j.trigger("xchange.xdsoft"),a},t.getWeekOfYear=function(e){var t=new Date(e.getFullYear(),0,1);return Math.ceil(((e-t)/864e5+t.getDay()+1)/7)},t.strToDateTime=function(e){var a,r,o=[];return e&&e instanceof Date&&t.isValidDate(e)?e:(o=/^(\+|\-)(.*)$/.exec(e),o&&(o[2]=n.parseDate(o[2],W.formatDate)),o&&o[2]?(a=o[2].getTime()-6e4*o[2].getTimezoneOffset(),r=new Date(t.now(!0).getTime()+parseInt(o[1]+"1",10)*a)):r=e?n.parseDate(e,W.format):t.now(),t.isValidDate(r)||(r=t.now()),r)},t.strToDate=function(e){if(e&&e instanceof Date&&t.isValidDate(e))return e;var a=e?n.parseDate(e,W.formatDate):t.now(!0);return t.isValidDate(a)||(a=t.now(!0)),a},t.strtotime=function(e){if(e&&e instanceof Date&&t.isValidDate(e))return e;var a=e?n.parseDate(e,W.formatTime):t.now(!0);return t.isValidDate(a)||(a=t.now(!0)),a},t.str=function(){return n.formatDate(t.currentTime,W.format)},t.currentTime=this.now()},Y=new s,B.on("touchend click",function(e){e.preventDefault(),j.data("changed",!0),Y.setCurrentTime(i()),a.val(Y.str()),j.trigger("close.xdsoft")}),z.find(".xdsoft_today_button").on("touchend mousedown.xdsoft",function(){j.data("changed",!0),Y.setCurrentTime(0),j.trigger("afterOpen.xdsoft")}).on("dblclick.xdsoft",function(){var e,t,n=Y.getCurrentTime();n=new Date(n.getFullYear(),n.getMonth(),n.getDate()),e=Y.strToDate(W.minDate),e=new Date(e.getFullYear(),e.getMonth(),e.getDate()),e>n||(t=Y.strToDate(W.maxDate),t=new Date(t.getFullYear(),t.getMonth(),t.getDate()),n>t||(a.val(Y.str()),a.trigger("change"),j.trigger("close.xdsoft")))}),z.find(".xdsoft_prev,.xdsoft_next").on("touchend mousedown.xdsoft",function(){var t=e(this),a=0,n=!1;!function r(e){t.hasClass(W.next)?Y.nextMonth():t.hasClass(W.prev)&&Y.prevMonth(),W.monthChangeSpinner&&(n||(a=setTimeout(r,e||100)))}(500),e([document.body,window]).on("touchend mouseup.xdsoft",function o(){clearTimeout(a),n=!0,e([document.body,window]).off("touchend mouseup.xdsoft",o)})}),N.find(".xdsoft_prev,.xdsoft_next").on("touchend mousedown.xdsoft",function(){var t=e(this),a=0,n=!1,r=110;!function o(e){var i=L[0].clientHeight,s=E[0].offsetHeight,d=Math.abs(parseInt(E.css("marginTop"),10));t.hasClass(W.next)&&s-i-W.timeHeightInTimePicker>=d?E.css("marginTop","-"+(d+W.timeHeightInTimePicker)+"px"):t.hasClass(W.prev)&&d-W.timeHeightInTimePicker>=0&&E.css("marginTop","-"+(d-W.timeHeightInTimePicker)+"px"),L.trigger("scroll_element.xdsoft_scroller",[Math.abs(parseInt(E.css("marginTop"),10)/(s-i))]),r=r>10?10:r-10,n||(a=setTimeout(o,e||r))}(500),e([document.body,window]).on("touchend mouseup.xdsoft",function i(){clearTimeout(a),n=!0,e([document.body,window]).off("touchend mouseup.xdsoft",i)})}),C=0,j.on("xchange.xdsoft",function(t){clearTimeout(C),C=setTimeout(function(){(void 0===Y.currentTime||null===Y.currentTime)&&(Y.currentTime=Y.now());for(var t,a,i,s,d,u,l,f,c,h,m="",g=new Date(Y.currentTime.getFullYear(),Y.currentTime.getMonth(),1,12,0,0),p=0,y=Y.now(),v=!1,b=!1,k=[],x=!0,D="",T="";g.getDay()!==W.dayOfWeekStart;)g.setDate(g.getDate()-1);for(m+="<table><thead><tr>",W.weeks&&(m+="<th></th>"),t=0;7>t;t+=1)m+="<th>"+W.i18n[o].dayOfWeekShort[(t+W.dayOfWeekStart)%7]+"</th>";for(m+="</tr></thead>",m+="<tbody>",W.maxDate!==!1&&(v=Y.strToDate(W.maxDate),v=new Date(v.getFullYear(),v.getMonth(),v.getDate(),23,59,59,999)),W.minDate!==!1&&(b=Y.strToDate(W.minDate),b=new Date(b.getFullYear(),b.getMonth(),b.getDate()));p<Y.currentTime.countDaysInMonth()||g.getDay()!==W.dayOfWeekStart||Y.currentTime.getMonth()===g.getMonth();)k=[],p+=1,i=g.getDay(),s=g.getDate(),d=g.getFullYear(),u=g.getMonth(),l=Y.getWeekOfYear(g),h="",k.push("xdsoft_date"),f=W.beforeShowDay&&e.isFunction(W.beforeShowDay.call)?W.beforeShowDay.call(j,g):null,v!==!1&&g>v||b!==!1&&b>g||f&&f[0]===!1?k.push("xdsoft_disabled"):-1!==W.disabledDates.indexOf(n.formatDate(g,W.formatDate))?k.push("xdsoft_disabled"):-1!==W.disabledWeekDays.indexOf(i)&&k.push("xdsoft_disabled"),f&&""!==f[1]&&k.push(f[1]),Y.currentTime.getMonth()!==u&&k.push("xdsoft_other_month"),(W.defaultSelect||j.data("changed"))&&n.formatDate(Y.currentTime,W.formatDate)===n.formatDate(g,W.formatDate)&&k.push("xdsoft_current"),n.formatDate(y,W.formatDate)===n.formatDate(g,W.formatDate)&&k.push("xdsoft_today"),(0===g.getDay()||6===g.getDay()||-1!==W.weekends.indexOf(n.formatDate(g,W.formatDate)))&&k.push("xdsoft_weekend"),void 0!==W.highlightedDates[n.formatDate(g,W.formatDate)]&&(a=W.highlightedDates[n.formatDate(g,W.formatDate)],k.push(void 0===a.style?"xdsoft_highlighted_default":a.style),h=void 0===a.desc?"":a.desc),W.beforeShowDay&&e.isFunction(W.beforeShowDay)&&k.push(W.beforeShowDay(g)),x&&(m+="<tr>",x=!1,W.weeks&&(m+="<th>"+l+"</th>")),m+='<td data-date="'+s+'" data-month="'+u+'" data-year="'+d+'" class="xdsoft_date xdsoft_day_of_week'+g.getDay()+" "+k.join(" ")+'" title="'+h+'"><div>'+s+"</div></td>",g.getDay()===W.dayOfWeekStartPrev&&(m+="</tr>",x=!0),g.setDate(s+1);if(m+="</tbody></table>",I.html(m),z.find(".xdsoft_label span").eq(0).text(W.i18n[o].months[Y.currentTime.getMonth()]),z.find(".xdsoft_label span").eq(1).text(Y.currentTime.getFullYear()),D="",T="",u="",c=function(t,a){var r,o,i=Y.now(),s=W.allowTimes&&e.isArray(W.allowTimes)&&W.allowTimes.length;i.setHours(t),t=parseInt(i.getHours(),10),i.setMinutes(a),a=parseInt(i.getMinutes(),10),r=new Date(Y.currentTime),r.setHours(t),r.setMinutes(a),k=[],(W.minDateTime!==!1&&W.minDateTime>r||W.maxTime!==!1&&Y.strtotime(W.maxTime).getTime()<i.getTime()||W.minTime!==!1&&Y.strtotime(W.minTime).getTime()>i.getTime())&&k.push("xdsoft_disabled"),(W.minDateTime!==!1&&W.minDateTime>r||W.disabledMinTime!==!1&&i.getTime()>Y.strtotime(W.disabledMinTime).getTime()&&W.disabledMaxTime!==!1&&i.getTime()<Y.strtotime(W.disabledMaxTime).getTime())&&k.push("xdsoft_disabled"),o=new Date(Y.currentTime),o.setHours(parseInt(Y.currentTime.getHours(),10)),s||o.setMinutes(Math[W.roundTime](Y.currentTime.getMinutes()/W.step)*W.step),(W.initTime||W.defaultSelect||j.data("changed"))&&o.getHours()===parseInt(t,10)&&(!s&&W.step>59||o.getMinutes()===parseInt(a,10))&&(W.defaultSelect||j.data("changed")?k.push("xdsoft_current"):W.initTime&&k.push("xdsoft_init_time")),parseInt(y.getHours(),10)===parseInt(t,10)&&parseInt(y.getMinutes(),10)===parseInt(a,10)&&k.push("xdsoft_today"),D+='<div class="xdsoft_time '+k.join(" ")+'" data-hour="'+t+'" data-minute="'+a+'">'+n.formatDate(i,W.formatTime)+"</div>"},W.allowTimes&&e.isArray(W.allowTimes)&&W.allowTimes.length)for(p=0;p<W.allowTimes.length;p+=1)T=Y.strtotime(W.allowTimes[p]).getHours(),u=Y.strtotime(W.allowTimes[p]).getMinutes(),c(T,u);else for(p=0,t=0;p<(W.hours12?12:24);p+=1)for(t=0;60>t;t+=W.step)T=(10>p?"0":"")+p,u=(10>t?"0":"")+t,c(T,u);for(E.html(D),r="",p=0,p=parseInt(W.yearStart,10)+W.yearOffset;p<=parseInt(W.yearEnd,10)+W.yearOffset;p+=1)r+='<div class="xdsoft_option '+(Y.currentTime.getFullYear()===p?"xdsoft_current":"")+'" data-value="'+p+'">'+p+"</div>";for(G.children().eq(0).html(r),p=parseInt(W.monthStart,10),r="";p<=parseInt(W.monthEnd,10);p+=1)r+='<div class="xdsoft_option '+(Y.currentTime.getMonth()===p?"xdsoft_current":"")+'" data-value="'+p+'">'+W.i18n[o].months[p]+"</div>";V.children().eq(0).html(r),e(j).trigger("generate.xdsoft")},10),t.stopPropagation()}).on("afterOpen.xdsoft",function(){if(W.timepicker){var e,t,a,n;E.find(".xdsoft_current").length?e=".xdsoft_current":E.find(".xdsoft_init_time").length&&(e=".xdsoft_init_time"),e?(t=L[0].clientHeight,a=E[0].offsetHeight,n=E.find(e).index()*W.timeHeightInTimePicker+1,n>a-t&&(n=a-t),L.trigger("scroll_element.xdsoft_scroller",[parseInt(n,10)/(a-t)])):L.trigger("scroll_element.xdsoft_scroller",[0])}}),F=0,I.on("touchend click.xdsoft","td",function(t){t.stopPropagation(),F+=1;var n=e(this),r=Y.currentTime;return(void 0===r||null===r)&&(Y.currentTime=Y.now(),r=Y.currentTime),n.hasClass("xdsoft_disabled")?!1:(r.setDate(1),r.setFullYear(n.data("year")),r.setMonth(n.data("month")),r.setDate(n.data("date")),j.trigger("select.xdsoft",[r]),a.val(Y.str()),W.onSelectDate&&e.isFunction(W.onSelectDate)&&W.onSelectDate.call(j,Y.currentTime,j.data("input"),t),j.data("changed",!0),j.trigger("xchange.xdsoft"),j.trigger("changedatetime.xdsoft"),(F>1||W.closeOnDateSelect===!0||W.closeOnDateSelect===!1&&!W.timepicker)&&!W.inline&&j.trigger("close.xdsoft"),void setTimeout(function(){F=0},200))}),E.on("touchend click.xdsoft","div",function(t){t.stopPropagation();var a=e(this),n=Y.currentTime;return(void 0===n||null===n)&&(Y.currentTime=Y.now(),n=Y.currentTime),a.hasClass("xdsoft_disabled")?!1:(n.setHours(a.data("hour")),n.setMinutes(a.data("minute")),j.trigger("select.xdsoft",[n]),j.data("input").val(Y.str()),W.onSelectTime&&e.isFunction(W.onSelectTime)&&W.onSelectTime.call(j,Y.currentTime,j.data("input"),t),j.data("changed",!0),j.trigger("xchange.xdsoft"),j.trigger("changedatetime.xdsoft"),void(W.inline!==!0&&W.closeOnTimeSelect===!0&&j.trigger("close.xdsoft")))}),J.on("mousewheel.xdsoft",function(e){return W.scrollMonth?(e.deltaY<0?Y.nextMonth():Y.prevMonth(),!1):!0}),a.on("mousewheel.xdsoft",function(e){return W.scrollInput?!W.datepicker&&W.timepicker?(P=E.find(".xdsoft_current").length?E.find(".xdsoft_current").eq(0).index():0,P+e.deltaY>=0&&P+e.deltaY<E.children().length&&(P+=e.deltaY),E.children().eq(P).length&&E.children().eq(P).trigger("mousedown"),!1):W.datepicker&&!W.timepicker?(J.trigger(e,[e.deltaY,e.deltaX,e.deltaY]),a.val&&a.val(Y.str()),j.trigger("changedatetime.xdsoft"),!1):void 0:!0}),j.on("changedatetime.xdsoft",function(t){if(W.onChangeDateTime&&e.isFunction(W.onChangeDateTime)){var a=j.data("input");W.onChangeDateTime.call(j,Y.currentTime,a,t),delete W.value,a.trigger("change")}}).on("generate.xdsoft",function(){W.onGenerate&&e.isFunction(W.onGenerate)&&W.onGenerate.call(j,Y.currentTime,j.data("input")),R&&(j.trigger("afterOpen.xdsoft"),R=!1)}).on("click.xdsoft",function(e){e.stopPropagation()}),P=0,A=function(){var t,a=j.data("input").offset(),n=j.data("input")[0],r=a.top+n.offsetHeight-1,o=a.left,i="absolute";"rtl"==j.data("input").parent().css("direction")&&(o-=j.outerWidth()-j.data("input").outerWidth()),W.fixed?(r-=e(window).scrollTop(),o-=e(window).scrollLeft(),i="fixed"):(r+n.offsetHeight>e(window).height()+e(window).scrollTop()&&(r=a.top-n.offsetHeight+1),0>r&&(r=0),o+n.offsetWidth>e(window).width()&&(o=e(window).width()-n.offsetWidth)),t=j[0];do if(t=t.parentNode,"relative"===window.getComputedStyle(t).getPropertyValue("position")&&e(window).width()>=t.offsetWidth){o-=(e(window).width()-t.offsetWidth)/2;break}while("HTML"!==t.nodeName);j.css({left:o,top:r,position:i})},j.on("open.xdsoft",function(t){var a=!0;W.onShow&&e.isFunction(W.onShow)&&(a=W.onShow.call(j,Y.currentTime,j.data("input"),t)),a!==!1&&(j.show(),A(),e(window).off("resize.xdsoft",A).on("resize.xdsoft",A),W.closeOnWithoutClick&&e([document.body,window]).on("touchstart mousedown.xdsoft",function n(){j.trigger("close.xdsoft"),e([document.body,window]).off("touchstart mousedown.xdsoft",n)}))}).on("close.xdsoft",function(t){var a=!0;z.find(".xdsoft_month,.xdsoft_year").find(".xdsoft_select").hide(),W.onClose&&e.isFunction(W.onClose)&&(a=W.onClose.call(j,Y.currentTime,j.data("input"),t)),a===!1||W.opened||W.inline||j.hide(),t.stopPropagation()}).on("toggle.xdsoft",function(){j.trigger(j.is(":visible")?"close.xdsoft":"open.xdsoft")}).data("input",a),U=0,q=0,j.data("xdsoft_datetime",Y),j.setOptions(W),Y.setCurrentTime(i()),a.data("xdsoft_datetimepicker",j).on("open.xdsoft focusin.xdsoft mousedown.xdsoft touchstart",function(){a.is(":disabled")||a.data("xdsoft_datetimepicker").is(":visible")&&W.closeOnInputClick||(clearTimeout(U),U=setTimeout(function(){a.is(":disabled")||(R=!0,Y.setCurrentTime(i()),j.trigger("open.xdsoft"))},100))}).on("keydown.xdsoft",function(t){var a,n=(this.value,t.which);return-1!==[m].indexOf(n)&&W.enterLikeTab?(a=e("input:visible,textarea:visible,button:visible,a:visible"),j.trigger("close.xdsoft"),a.eq(a.index(this)+1).focus(),!1):-1!==[x].indexOf(n)?(j.trigger("close.xdsoft"),!0):void 0})},s=function(t){var a=t.data("xdsoft_datetimepicker");a&&(a.data("xdsoft_datetime",null),a.remove(),t.data("xdsoft_datetimepicker",null).off(".xdsoft"),e(window).off("resize.xdsoft"),e([window,document.body]).off("mousedown.xdsoft touchstart"),t.unmousewheel&&t.unmousewheel())},e(document).off("keydown.xdsoftctrl keyup.xdsoftctrl").on("keydown.xdsoftctrl",function(e){e.keyCode===c&&(_=!0)}).on("keyup.xdsoftctrl",function(e){e.keyCode===c&&(_=!1)}),this.each(function(){var t,a=e(this).data("xdsoft_datetimepicker");if(a){if("string"===e.type(r))switch(r){case"show":e(this).select().focus(),a.trigger("open.xdsoft");break;case"hide":a.trigger("close.xdsoft");break;case"toggle":a.trigger("toggle.xdsoft");break;case"destroy":s(e(this));break;case"reset":this.value=this.defaultValue,this.value&&a.data("xdsoft_datetime").isValidDate(n.parseDate(this.value,W.format))||a.data("changed",!1),a.data("xdsoft_datetime").setCurrentTime(this.value);break;case"validate":t=a.data("input"),t.trigger("blur.xdsoft")}else a.setOptions(r);return 0}"string"!==e.type(r)&&(!W.lazyInit||W.open||W.inline?i(e(this)):F(e(this)))})},e.fn.datetimepicker.defaults=a}),function(e){"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?module.exports=e:e(jQuery)}(function(e){function t(t){var i=t||window.event,s=d.call(arguments,1),u=0,f=0,c=0,h=0,m=0,g=0;if(t=e.event.fix(i),t.type="mousewheel","detail"in i&&(c=-1*i.detail),"wheelDelta"in i&&(c=i.wheelDelta),"wheelDeltaY"in i&&(c=i.wheelDeltaY),"wheelDeltaX"in i&&(f=-1*i.wheelDeltaX),"axis"in i&&i.axis===i.HORIZONTAL_AXIS&&(f=-1*c,c=0),u=0===c?f:c,"deltaY"in i&&(c=-1*i.deltaY,u=c),"deltaX"in i&&(f=i.deltaX,0===c&&(u=-1*f)),0!==c||0!==f){if(1===i.deltaMode){var p=e.data(this,"mousewheel-line-height");u*=p,c*=p,f*=p}else if(2===i.deltaMode){var y=e.data(this,"mousewheel-page-height");u*=y,c*=y,f*=y}if(h=Math.max(Math.abs(c),Math.abs(f)),(!o||o>h)&&(o=h,n(i,h)&&(o/=40)),n(i,h)&&(u/=40,f/=40,c/=40),u=Math[u>=1?"floor":"ceil"](u/o),f=Math[f>=1?"floor":"ceil"](f/o),c=Math[c>=1?"floor":"ceil"](c/o),l.settings.normalizeOffset&&this.getBoundingClientRect){var v=this.getBoundingClientRect();m=t.clientX-v.left,g=t.clientY-v.top}return t.deltaX=f,t.deltaY=c,t.deltaFactor=o,t.offsetX=m,t.offsetY=g,t.deltaMode=0,s.unshift(t,u,f,c),r&&clearTimeout(r),r=setTimeout(a,200),(e.event.dispatch||e.event.handle).apply(this,s)}}function a(){o=null}function n(e,t){return l.settings.adjustOldDeltas&&"mousewheel"===e.type&&t%120===0}var r,o,i=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],s="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],d=Array.prototype.slice;if(e.event.fixHooks)for(var u=i.length;u;)e.event.fixHooks[i[--u]]=e.event.mouseHooks;var l=e.event.special.mousewheel={version:"3.1.12",setup:function(){if(this.addEventListener)for(var a=s.length;a;)this.addEventListener(s[--a],t,!1);else this.onmousewheel=t;e.data(this,"mousewheel-line-height",l.getLineHeight(this)),e.data(this,"mousewheel-page-height",l.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var a=s.length;a;)this.removeEventListener(s[--a],t,!1);else this.onmousewheel=null;e.removeData(this,"mousewheel-line-height"),e.removeData(this,"mousewheel-page-height")},getLineHeight:function(t){var a=e(t),n=a["offsetParent"in e.fn?"offsetParent":"parent"]();return n.length||(n=e("body")),parseInt(n.css("fontSize"),10)||parseInt(a.css("fontSize"),10)||16},getPageHeight:function(t){return e(t).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};e.fn.extend({mousewheel:function(e){return e?this.bind("mousewheel",e):this.trigger("mousewheel")},unmousewheel:function(e){return this.unbind("mousewheel",e)}})}); \ No newline at end of file
diff --git a/js/last.js b/js/last.js
new file mode 100644
index 00000000..e107ef97
--- /dev/null
+++ b/js/last.js
@@ -0,0 +1,166 @@
+var newUserDates = [];
+var newUserTypes = [];
+
+var max_votes = 0;
+var values_changed = false;
+
+$(document).ready(function () {
+ var cells = [];
+ cells = document.getElementsByClassName('cl_click');
+ // loop over 'user' cells
+ for (var i = 0; i < cells.length; i++){
+ // fill arrays (if this is edit)
+ if (cells[i].className.indexOf('poll-cell-active-not') >= 0){
+ newUserTypes.push(0);
+ newUserDates.push(cells[i].id);
+ } else if (cells[i].className.indexOf('poll-cell-active-is') >= 0){
+ newUserTypes.push(1);
+ newUserDates.push(cells[i].id);
+ } else if(cells[i].className.indexOf('poll-cell-active-maybe') >= 0){
+ newUserTypes.push(2);
+ newUserDates.push(cells[i].id);
+ } else {
+ newUserTypes.push(-1);
+ newUserDates.push(cells[i].id);
+ }
+ }
+
+ $('#button_home').click(function() {
+ document.getElementById('j').value = 'home';
+ document.finish_poll.submit();
+ });
+
+ $('#submit_finish_poll').click(function() {
+ var form = document.finish_poll;
+ var comm = document.getElementById('comment_box');
+ var ac_user = '';
+ var ac = document.getElementById('user_name');
+ if (ac != null) {
+ if(ac.value.length >= 3){
+ ac_user = ac.value;
+ } else {
+ alert(t('polls', 'You are not registered.\nPlease enter your name to vote\n(at least 3 characters).'));
+ return;
+ }
+ }
+ check_notif = document.getElementById('check_notif');
+
+ form.elements['options'].value = JSON.stringify({
+ dates: newUserDates,
+ values: newUserTypes,
+ ac_user: ac_user,
+ check_notif: ((check_notif && check_notif.checked) ? 'true' : 'false'),
+ values_changed: (values_changed ? 'true' : 'false')
+ });
+ form.submit();
+ });
+
+ $('#submit_send_comment').click(function() {
+ var form = document.send_comment;
+ var comm = document.getElementById('comment_box');
+ form.elements['options'].value = JSON.stringify({
+ comment: comm.value,
+ });
+ form.submit();
+ });
+});
+
+$(document).on('click', '.poll-cell-active-un', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(2);
+ $(this).switchClass('poll-cell-active-un', 'poll-cell-active-maybe');
+ $(this).switchClass('icon-info', 'icon-more');
+});
+
+$(document).on('click', '.poll-cell-active-not', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(2);
+ var total_no = document.getElementById('id_n_' + ts);
+ total_no.innerHTML = parseInt(total_no.innerHTML) - 1;
+ $(this).switchClass('poll-cell-active-not', 'poll-cell-active-maybe');
+ $(this).switchClass('icon-close', 'icon-more');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+$(document).on('click', '.poll-cell-active-maybe', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(1);
+ var total_yes = document.getElementById('id_y_' + ts);
+ total_yes.innerHTML = parseInt(total_yes.innerHTML) + 1;
+ $(this).switchClass('poll-cell-active-maybe', 'poll-cell-active-is');
+ $(this).switchClass('icon-more', 'icon-checkmark');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+$(document).on('click', '.poll-cell-active-is', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(0);
+ var total_yes = document.getElementById('id_y_' + ts);
+ var total_no = document.getElementById('id_n_' + ts);
+ total_yes.innerHTML = parseInt(total_yes.innerHTML) - 1;
+ total_no.innerHTML = parseInt(total_no.innerHTML) + 1;
+ $(this).switchClass('poll-cell-active-is', 'poll-cell-active-not');
+ $(this).switchClass('icon-checkmark', 'icon-close');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+function findNewMaxCount(){
+ var cell_tot_y = document.getElementsByClassName('cl_total_y');
+ var cell_tot_n = document.getElementsByClassName('cl_total_n');
+ max_votes = 0;
+ for(var i=0; i<cell_tot_y.length; i++) {
+ var currYes = parseInt(cell_tot_y[i].innerHTML);
+ var currNo = parseInt(cell_tot_n[i].innerHTML);
+ var curr = currYes - currNo;
+ if(curr > max_votes) max_votes = curr;
+ }
+}
+
+function updateStrongCounts(){
+ var cell_tot_y = document.getElementsByClassName('cl_total_y');
+ var cell_tot_n = document.getElementsByClassName('cl_total_n');
+
+ for(var i=0; i<cell_tot_y.length; i++) {
+ var cell_win = document.getElementById('id_total_' + i);
+ var curr = parseInt(cell_tot_y[i].innerHTML) - parseInt(cell_tot_n[i].innerHTML);
+ if(curr < max_votes) {
+ cell_win.className = 'win_row';
+ cell_tot_y[i].style.fontWeight = 'normal';
+ }
+ else {
+ cell_tot_y[i].style.fontWeight = 'bold';
+ cell_win.className = 'win_row icon-checkmark';
+ }
+ }
+}
diff --git a/js/start.js b/js/start.js
new file mode 100755
index 00000000..65a1101b
--- /dev/null
+++ b/js/start.js
@@ -0,0 +1,57 @@
+var edit_access_id = null; // set if called from the summary page
+
+$(document).ready(function () {
+ edit_access_id = null;
+ // users, groups
+ var elem = document.getElementById('select');
+ if (elem) elem.onclick = showAccessDialog;
+ elem = document.getElementById('button_close_access');
+ if (elem) elem.onclick = closeAccessDialog;
+
+ cells = document.getElementsByClassName('cl_group_item');
+ for (var i = 0; i < cells.length; i++) {
+ cells[i].onclick = groupItemClicked;
+ }
+ cells = document.getElementsByClassName('cl_user_item');
+ for (var i = 0; i < cells.length; i++) {
+ cells[i].onclick = userItemClicked;
+ }
+
+ var cells = document.getElementsByClassName('cl_delete');
+ for (var i = 0; i < cells.length; i++) {
+ var cell = cells[i];
+ cells[i].onclick = deletePoll;
+ }
+
+ // set "show poll url" handler
+ cells = document.getElementsByClassName('cl_poll_url');
+ for (var i = 0; i < cells.length; i++) {
+ var cell = cells[i];
+ cells[i].onclick = function(e) {
+ // td has inner 'input'; value is poll url
+ var cell = e.target;
+ var url = cell.getElementsByTagName('input')[0].value;
+ window.prompt(t('polls','Copy to clipboard: Ctrl+C, Enter'), url);
+ }
+ }
+});
+
+function deletePoll(e) {
+ var tr = this.parentNode.parentNode;
+ var titleTd = tr.firstChild;
+ //check if first child is whitespace text element
+ if(titleTd.nodeName == '#text') titleTd = titleTd.nextSibling;
+ var tdElem = titleTd.firstChild;
+ //again, whitespace check
+ if(tdElem.nodeName == '#text') tdElem = tdElem.nextSibling;
+ var str = t('polls', 'Do you really want to delete that poll?') + '\n\n' + tdElem.innerHTML;
+ if (confirm(str)) {
+ var form = document.form_delete_poll;
+ var hiddenId = document.createElement("input");
+ hiddenId.setAttribute("name", "pollId");
+ hiddenId.setAttribute("type", "hidden");
+ form.appendChild(hiddenId);
+ form.elements['pollId'].value = this.id.split('_')[2];
+ form.submit();
+ }
+}
diff --git a/js/vote.js b/js/vote.js
new file mode 100644
index 00000000..8bde3e15
--- /dev/null
+++ b/js/vote.js
@@ -0,0 +1,156 @@
+var newUserDates = [];
+var newUserTypes = [];
+
+var max_votes = 0;
+var values_changed = false;
+
+$(document).ready(function () {
+ var cells = [];
+ cells = document.getElementsByClassName('cl_click');
+ // loop over 'user' cells
+ for (var i = 0; i < cells.length; i++){
+ // fill arrays (if this is edit)
+ if (cells[i].className.indexOf('poll-cell-active-not') >= 0){
+ newUserTypes.push(0);
+ newUserDates.push(cells[i].id);
+ } else if (cells[i].className.indexOf('poll-cell-active-is') >= 0){
+ newUserTypes.push(1);
+ newUserDates.push(cells[i].id);
+ } else if(cells[i].className.indexOf('poll-cell-active-maybe') >= 0){
+ newUserTypes.push(2);
+ newUserDates.push(cells[i].id);
+ } else {
+ newUserTypes.push(-1);
+ newUserDates.push(cells[i].id);
+ }
+ }
+
+ $('#submit_finish_vote').click(function() {
+ var form = document.finish_vote;
+ var ac = document.getElementById('user_name');
+ if (ac != null) {
+ if(ac.value.length >= 3){
+ form.elements['userId'].value = ac.value;
+ } else {
+ alert(t('polls', 'You are not registered.\nPlease enter your name to vote\n(at least 3 characters).'));
+ return;
+ }
+ }
+ check_notif = document.getElementById('check_notif');
+ form.elements['dates'].value = JSON.stringify(newUserDates);
+ form.elements['types'].value = JSON.stringify(newUserTypes);
+ form.elements['notif'].value = (check_notif && check_notif.checked) ? 'true' : 'false';
+ form.elements['changed'].value = values_changed ? 'true' : 'false';
+ form.submit();
+ });
+
+ $('#submit_send_comment').click(function() {
+ var form = document.send_comment;
+ var comm = document.getElementById('commentBox');
+ if(comm.value.length <= 0) {
+ alert(t('polls', 'Please add some text to your comment before submitting it.'));
+ return;
+ }
+ form.submit();
+ });
+});
+
+$(document).on('click', '.poll-cell-active-un', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(2);
+ $(this).switchClass('poll-cell-active-un', 'poll-cell-active-maybe');
+ $(this).switchClass('icon-info', 'icon-more');
+});
+
+$(document).on('click', '.poll-cell-active-not', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(2);
+ var total_no = document.getElementById('id_n_' + ts);
+ total_no.innerHTML = parseInt(total_no.innerHTML) - 1;
+ $(this).switchClass('poll-cell-active-not', 'poll-cell-active-maybe');
+ $(this).switchClass('icon-close', 'icon-more');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+$(document).on('click', '.poll-cell-active-maybe', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(1);
+ var total_yes = document.getElementById('id_y_' + ts);
+ total_yes.innerHTML = parseInt(total_yes.innerHTML) + 1;
+ $(this).switchClass('poll-cell-active-maybe', 'poll-cell-active-is');
+ $(this).switchClass('icon-more', 'icon-checkmark');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+$(document).on('click', '.poll-cell-active-is', function(e) {
+ values_changed = true;
+ var ts = $(this).attr('id');
+ var index = newUserDates.indexOf(ts);
+ if(index > -1) {
+ newUserDates.splice(index, 1);
+ newUserTypes.splice(index, 1);
+ }
+ newUserDates.push(ts);
+ newUserTypes.push(0);
+ var total_yes = document.getElementById('id_y_' + ts);
+ var total_no = document.getElementById('id_n_' + ts);
+ total_yes.innerHTML = parseInt(total_yes.innerHTML) - 1;
+ total_no.innerHTML = parseInt(total_no.innerHTML) + 1;
+ $(this).switchClass('poll-cell-active-is', 'poll-cell-active-not');
+ $(this).switchClass('icon-checkmark', 'icon-close');
+ findNewMaxCount();
+ updateStrongCounts();
+});
+
+function findNewMaxCount(){
+ var cell_tot_y = document.getElementsByClassName('cl_total_y');
+ var cell_tot_n = document.getElementsByClassName('cl_total_n');
+ max_votes = 0;
+ for(var i=0; i<cell_tot_y.length; i++) {
+ var currYes = parseInt(cell_tot_y[i].innerHTML);
+ var currNo = parseInt(cell_tot_n[i].innerHTML);
+ var curr = currYes - currNo;
+ if(curr > max_votes) max_votes = curr;
+ }
+}
+
+function updateStrongCounts(){
+ var cell_tot_y = document.getElementsByClassName('cl_total_y');
+ var cell_tot_n = document.getElementsByClassName('cl_total_n');
+
+ for(var i=0; i<cell_tot_y.length; i++) {
+ var cell_win = document.getElementById('id_total_' + i);
+ var curr = parseInt(cell_tot_y[i].innerHTML) - parseInt(cell_tot_n[i].innerHTML);
+ if(curr < max_votes) {
+ cell_win.className = 'win_row';
+ cell_tot_y[i].style.fontWeight = 'normal';
+ }
+ else {
+ cell_tot_y[i].style.fontWeight = 'bold';
+ cell_win.className = 'win_row icon-checkmark';
+ }
+ }
+}
diff --git a/l10n/ca.json b/l10n/ca.json
new file mode 100644
index 00000000..60ceb132
--- /dev/null
+++ b/l10n/ca.json
@@ -0,0 +1,72 @@
+{ "translations": {
+ "Polls" : "Enquestes",
+ "Summary" : "Resum",
+ "Title" : "Titol",
+ "Description" : "Descripció",
+ "Created" : "Creat",
+ "Expires" : "Caduca",
+ "By" : "Per",
+ "Go to" : "Anar a",
+ "Create new poll" : "Crear una nova enquesta",
+ "Access (click for link)" : "Accés (click per l'enllaç)",
+ "Access" : "Accés",
+ "Registered users only" : "Només usuaris registrats",
+ "Public access" : "Accés públic",
+ "hidden" : "ocult",
+ "public" : "públic",
+ "registered" : "registrat",
+ "delete" : "esborrar",
+ "Next" : "Següent",
+ "Click on days to add or remove" : "Feu click als dies per afegir o treure",
+ "Select hour & minute, then click on time" : "Trieu hora i minut, després feu click a l'hora",
+ "Mon" : "Dll",
+ "Tue" : "Dm",
+ "Wed" : "Dc",
+ "Thu" : "Dj",
+ "Fri" : "Dv",
+ "Sat" : "Ds",
+ "Sun" : "Dg",
+ "click to add" : "click per afegir",
+ "date\\time" : "date\\hora",
+ "poll URL" : "URL enquesta",
+ "Total" : "Total",
+ "Comment" : "Comentari",
+ "Comments" : "Comentaris",
+ "Send" : "Enviar",
+ "Vote!" : "Vota!",
+ "Home" : "Inici",
+ "participated" : "participat",
+ "Yourself" : "Jo",
+ "Select" : "Trieu",
+ "Close" : "Tanqueu",
+ "Users" : "Usuaris",
+ "Groups" : "Grups",
+ "Are you sure you want to delete this poll" : "Esteu segur que voleu esborrar l'enquesta",
+ "You must enter at least a title for the new poll." : "Heu d'entrar al menys un titol per la nova enquesta.",
+ "Copy to clipboard: Ctrl+C, Enter" : "Copieu al porta-retalls: Ctrl+C, Intro",
+ "Thanks that you've voted. You can close the page now." : "Gracies pel vostre bot. Podeu tancar la pàgina ara.",
+ "Nothing selected!\nClick on cells to turn them green." : "Res seleccionat!\nFeu click a les cel·les per posar-les en verd",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "No esteu registrat.\nEntreu el vostre nom per votar\n(mínim 3 caràcters!)",
+ "You already have an item with the same text" : "Ja teniu un item amb el mateix nom",
+ "Please choose the groups or users you want to add to your poll." : "Trieu els grups o usuaris que voleu afegir a l'enquesta.",
+ "Click to get link" : "Click per obtenir el link",
+ "Edit access" : "Editar accés",
+ "Type" : "Tipus",
+ "Event schedule" : "Horari de l'event",
+ "Text based" : "Basat en text",
+ "Text item" : "Element de text",
+ "Description (will be shown as tooltip on the summary page)" : "Descripció (es mostrarà indicació a la pàgina resum)",
+ "Poll expired" : "Enquesta expirada",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "L'enquesta va expirar el %s. Ja no es pot votar, però encara podeu comentar.",
+ "You are not allowed to view this poll or the poll does not exist." : "No teniu permís per votar en aquesta enquesta o be no existeix.",
+ "Error" : "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s, <br/><br/><strong>%s</strong> us ha compartit l'enquesta '%s'. Per anar directament a l'enquesta, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s, <br/><br/><strong>%s</strong> ha comentat en l'enquesta '%s'.<br/><br/><i>%s</i><br/><br/>Per anar-hi directament, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s, <br/><br/><strong>%s</strong> ha participat en l'enquesta '%s'.<br/><br/>Per anar-hi directament, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "ownCloud Enquestes -- Nou comentari",
+ "ownCloud Polls -- New Participant" : "ownCloud Enquestes -- Nou Participant",
+ "ownCloud Polls -- New Poll" : "ownCloud Enquestes -- Nova enquesta",
+ "ownCloud Polls" : "ownCloud Enquestes",
+ "Receive notification email on activity" : "Rebre notificacions d'activitat per correu"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/ca.php b/l10n/ca.php
new file mode 100644
index 00000000..452bc8d8
--- /dev/null
+++ b/l10n/ca.php
@@ -0,0 +1,73 @@
+<?php
+$TRANSLATIONS = array(
+ "Polls" => "Enquestes",
+ "Summary" => "Resum",
+ "Title" => "Titol",
+ "Description" => "Descripció",
+ "Created" => "Creat",
+ "Expires" => "Caduca",
+ "By" => "Per",
+ "Go to" => "Anar a",
+ "Create new poll" => "Crear una nova enquesta",
+ "Access (click for link)" => "Accés (click per l'enllaç)",
+ "Access" => "Accés",
+ "Registered users only" => "Només usuaris registrats",
+ "Public access" => "Accés públic",
+ "hidden" => "ocult",
+ "public" => "públic",
+ "registered" => "registrat",
+ "delete" => "esborrar",
+ "Next" => "Següent",
+ "Click on days to add or remove" => "Feu click als dies per afegir o treure",
+ "Select hour & minute, then click on time" => "Trieu hora i minut, després feu click a l'hora",
+ "Mon" => "Dll",
+ "Tue" => "Dm",
+ "Wed" => "Dc",
+ "Thu" => "Dj",
+ "Fri" => "Dv",
+ "Sat" => "Ds",
+ "Sun" => "Dg",
+ "click to add" => "click per afegir",
+ "date\\time" => "date\\hora",
+ "poll URL" => "URL enquesta",
+ "Total" => "Total",
+ "Comment" => "Comentari",
+ "Comments" => "Comentaris",
+ "Send" => "Enviar",
+ "Vote!" => "Vota!",
+ "Home" => "Inici",
+ "participated" => "participat",
+ "Yourself" => "Jo",
+ "Select" => "Trieu",
+ "Close" => "Tanqueu",
+ "Users" => "Usuaris",
+ "Groups" => "Grups",
+ "Are you sure you want to delete this poll" => "Esteu segur que voleu esborrar l'enquesta",
+ "You must enter at least a title for the new poll." => "Heu d'entrar al menys un titol per la nova enquesta.",
+ "Copy to clipboard: Ctrl+C, Enter" => "Copieu al porta-retalls: Ctrl+C, Intro",
+ "Thanks that you've voted. You can close the page now." => "Gracies pel vostre bot. Podeu tancar la pàgina ara.",
+ "Nothing selected!\nClick on cells to turn them green." => "Res seleccionat!\nFeu click a les cel·les per posar-les en verd",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" => "No esteu registrat.\nEntreu el vostre nom per votar\n(mínim 3 caràcters!)",
+ "You already have an item with the same text" => "Ja teniu un item amb el mateix nom",
+ "Please choose the groups or users you want to add to your poll." => "Trieu els grups o usuaris que voleu afegir a l'enquesta.",
+ "Click to get link" => "Click per obtenir el link",
+ "Edit access" => "Editar accés",
+ "Type" => "Tipus",
+ "Event schedule" => "Horari de l'event",
+ "Text based" => "Basat en text",
+ "Text item" => "Element de text",
+ "Description (will be shown as tooltip on the summary page)" => "Descripció (es mostrarà indicació a la pàgina resum)",
+ "Poll expired" => "Enquesta expirada",
+ "The poll expired on %s. Voting is disabled, but you can still comment." => "L'enquesta va expirar el %s. Ja no es pot votar, però encara podeu comentar.",
+ "You are not allowed to view this poll or the poll does not exist." => "No teniu permís per votar en aquesta enquesta o be no existeix.",
+ "Error" => "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s, <br/><br/><strong>%s</strong> us ha compartit l'enquesta '%s'. Per anar directament a l'enquesta, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s, <br/><br/><strong>%s</strong> ha comentat en l'enquesta '%s'.<br/><br/><i>%s</i><br/><br/>Per anar-hi directament, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s, <br/><br/><strong>%s</strong> ha participat en l'enquesta '%s'.<br/><br/>Per anar-hi directament, feu servir aquest enllaç: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" => "ownCloud Enquestes -- Nou comentari",
+ "ownCloud Polls -- New Participant" => "ownCloud Enquestes -- Nou Participant",
+ "ownCloud Polls -- New Poll" => "ownCloud Enquestes -- Nova enquesta",
+ "ownCloud Polls" => "ownCloud Enquestes",
+ "Receive notification email on activity" => "Rebre notificacions d'activitat per correu"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/l10n/de.json b/l10n/de.json
new file mode 100644
index 00000000..14e336bf
--- /dev/null
+++ b/l10n/de.json
@@ -0,0 +1,83 @@
+{ "translations": {
+ "Polls" : "Umfragen",
+ "Summary" : "Übersicht",
+ "No existing polls." : "Keine Umfragen vorhanden.",
+ "Title" : "Name",
+ "Description" : "Beschreibung",
+ "Please select at least one user or group!" : "Bitte wählen Sie mindestens einen Benutzer oder eine Gruppe aus!",
+ "Created" : "erstellt",
+ "Expires" : "Läuft ab",
+ "Never" : "Niemals",
+ "By" : "von",
+ "Go to" : "Gehe zu",
+ "Create new poll" : "Neue Umfrage erstellen",
+ "Access (click for link)" : "Zugriff (für Link klicken)",
+ "Access" : "Zugriff",
+ "Registered users only" : "Nur registrierte Benutzer",
+ "Public access" : "Öffentlicher Zugriff",
+ "hidden" : "versteckt",
+ "public" : "öffentlich",
+ "registered" : "für Registrierte",
+ "delete" : "löschen",
+ "Next" : "Weiter",
+ "Cancel" : "Abbrechen",
+ "Options" : "Optionen",
+ "Edit poll" : "Umfrage bearbeiten",
+ "Click on days to add or remove" : "Klicke auf die Tage um sie hinzuzufügen oder zu löschen",
+ "Select hour & minute, then click on time" : "Wähle Stunden und Minuten, dann klicke auf die Zeit",
+ "Mon" : "Mo",
+ "Tue" : "Di",
+ "Wed" : "Mi",
+ "Thu" : "Do",
+ "Fri" : "Fr",
+ "Sat" : "Sa",
+ "Sun" : "So",
+ "click to add" : "Klicke zum Hinzufügen",
+ "date\\time" : "Datum/Zeit",
+ "Poll URL" : "Umfrage-Link",
+ "Total" : "Gesamt",
+ "No description provided." : "Keine Beschreibung angegeben.",
+ "Write new Comment" : "Neuer Kommentar",
+ "Comments" : "Kommentare",
+ "No comments yet. Be the first." : "Bisher keine Kommentare. Sei der Erste.",
+ "Send!" : "Abschicken!",
+ "Vote!" : "Abstimmen!",
+ "Home" : "Startseite",
+ "participated" : "abgestimmt",
+ "Yourself" : "Dir",
+ "Select" : "Wählen",
+ "Close" : "Schließen",
+ "Users" : "Benutzer",
+ "Groups" : "Gruppen",
+ "Do you really want to delete that poll?" : "Sind Sie sicher, dass sie diese Umfrage löschen möchten?",
+ "You must enter at least a title for the new poll." : "Du musst zumindest einen Namen für die Umfrage angeben.",
+ "Copy to clipboard: Ctrl+C, Enter" : "In die Zwischenablage kopieren: Strg+C, Enter",
+ "Thanks that you've voted. You can close the page now." : "Danke, dass du abgestimmt hast. Du kannst die Seite jetzt schließen.",
+ "Nothing selected!\nClick on cells to turn them green." : "Nichts ausgewählt!\nKlicke auf die Elemente um sie auszuwählen (grün).",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "Du bist nicht registriert.\nBitte gebe deinen Namen ein um abzustimmen\n(mindestens 3 Zeichen!)",
+ "You already have an item with the same text" : "Du hast bereits ein Element mit dem gleichen Text.",
+ "Please choose the groups or users you want to add to your poll." : "Bitte wähle die Gruppen oder Benutzer aus, die du zu deiner Umfrage hinzufügen möchtest.",
+ "Click to get link" : "Klicke um den Link zu erhalten",
+ "Edit access" : "Zugriff ändern",
+ "Type" : "Art",
+ "Event schedule" : "Datumsangabe",
+ "Text based" : "Eigene Texte",
+ "Text item" : "Text",
+ "Dates" : "Termine",
+ "Description (will be shown as tooltip on the summary page)" : "Beschreibung (wird als Tooltip in der Übersicht angezeigt)",
+ "Poll expired" : "Umfrage abgelaufen",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "Die Umfrage lief am %s ab. Die Abstimmung ist geschlossen, aber es kann weiterhin kommentiert werden.",
+ "You are not allowed to view this poll or the poll does not exist." : "Dir fehlt die Berechtigung zur Anzeige dieser Abstimmung oder diese Abstimmung existiert nicht.",
+ "Error" : "Fehler",
+ "d.m.Y H:i" : "d.m.Y H:i",
+ "d.m.Y" : "d.m.Y",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' mit dir geteilt. Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' kommentiert.<br/><br/><i>%s</i><br/><br/>Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat an der Umfrage '%s' teilgenommen.<br/><br/>Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "ownCloud Umfragen -- Neuer Kommentar",
+ "ownCloud Polls -- New Participant" : "ownCloud Umfragen -- Neuer Teilnehmer",
+ "ownCloud Polls -- New Poll" : "ownCloud Umfragen -- Neue Umfrage",
+ "ownCloud Polls" : "ownCloud Umfragen",
+ "Receive notification email on activity" : "Erhalte Emails bei Änderungen"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/de.php b/l10n/de.php
new file mode 100644
index 00000000..3a01c0d4
--- /dev/null
+++ b/l10n/de.php
@@ -0,0 +1,84 @@
+<?php
+$TRANSLATIONS = array(
+ "Polls" => "Umfragen",
+ "Summary" => "Übersicht",
+ "No existing polls." => "Keine Umfragen vorhanden.",
+ "Title" => "Name",
+ "Description" => "Beschreibung",
+ "Please select at least one user or group!" => "Bitte wählen Sie mindestens einen Benutzer oder eine Gruppe aus!",
+ "Created" => "erstellt",
+ "Expires" => "Läuft ab",
+ "Never" => "Niemals",
+ "By" => "von",
+ "Go to" => "Gehe zu",
+ "Create new poll" => "Neue Umfrage erstellen",
+ "Access (click for link)" => "Zugriff (für Link klicken)",
+ "Access" => "Zugriff",
+ "Registered users only" => "Nur registrierte Benutzer",
+ "Public access" => "Öffentlicher Zugriff",
+ "hidden" => "versteckt",
+ "public" => "öffentlich",
+ "registered" => "für Registrierte",
+ "delete" => "löschen",
+ "Next" => "Weiter",
+ "Cancel" => "Abbrechen",
+ "Options" => "Optionen",
+ "Edit poll" => "Umfrage bearbeiten",
+ "Click on days to add or remove" => "Klicke auf die Tage um sie hinzuzufügen oder zu löschen",
+ "Select hour & minute, then click on time" => "Wähle Stunden und Minuten, dann klicke auf die Zeit",
+ "Mon" => "Mo",
+ "Tue" => "Di",
+ "Wed" => "Mi",
+ "Thu" => "Do",
+ "Fri" => "Fr",
+ "Sat" => "Sa",
+ "Sun" => "So",
+ "click to add" => "Klicke zum Hinzufügen",
+ "date\\time" => "Datum/Zeit",
+ "poll URL" => "Umfrage-Link",
+ "Total" => "Gesamt",
+ "No description provided." => "Keine Beschreibung angegeben.",
+ "Write new Comment" => "Neuer Kommentar",
+ "Comments" => "Kommentare",
+ "No comments yet. Be the first." => "Bisher keine Kommentare. Sei der Erste.",
+ "Send!" => "Abschicken!",
+ "Vote!" => "Abstimmen!",
+ "Home" => "Startseite",
+ "participated" => "abgestimmt",
+ "Yourself" => "Dir",
+ "Select" => "Wählen",
+ "Close" => "Schließen",
+ "Users" => "Benutzer",
+ "Groups" => "Gruppen",
+ "Do you really want to delete that poll?" => "Sind Sie sicher, dass sie diese Umfrage löschen möchten?",
+ "You must enter at least a title for the new poll." => "Sie müssen zumindest einen Namen für die Umfrage angeben.",
+ "Copy to clipboard: Ctrl+C, Enter" => "In die Zwischenablage kopieren: Strg+C, Enter",
+ "Thanks that you've voted. You can close the page now." => "Danke, dass sie abgestimmt haben. Sie können die Seite jetzt schließen.",
+ "Nothing selected!\nClick on cells to turn them green." => "Nichts ausgewählt!\nKlicke auf die Elemente um sie auszuwählen (grün).",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" => "Sie sind nicht registriert.\nBitte geben Sie ihren Namen ein um abzustimmen\n(mindestens 3 Zeichen!)",
+ "You already have an item with the same text" => "Sie haben bereits ein Element mit dem gleichen Text.",
+ "Please choose the groups or users you want to add to your poll." => "Bitte wählen Sie die Gruppen oder Benutzer aus, die Sie zu ihrer Umfrage hinzufügen möchten.",
+ "Click to get link" => "Klicken Sie um den Link zu erhalten",
+ "Edit access" => "Zugriff ändern",
+ "Type" => "Art",
+ "Event schedule" => "Datumsangabe",
+ "Text based" => "Eigene Texte",
+ "Text item" => "Text",
+ "Dates" => "Termine",
+ "Description (will be shown as tooltip on the summary page)" => "Beschreibung (wird als Tooltip in der Übersicht angezeigt)",
+ "Poll expired" => "Umfrage abgelaufen",
+ "The poll expired on %s. Voting is disabled, but you can still comment." => "Die Umfrage lief am %s ab. Die Abstimmung ist geschlossen, aber es kann weiterhin kommentiert werden.",
+ "You are not allowed to view this poll or the poll does not exist." => "Ihnen fehlt die Berechtigung zur Anzeige dieser Abstimmung oder diese Abstimmung existiert nicht.",
+ "Error" => "Fehler",
+ "d.m.Y H:i" => "d.m.Y H:i",
+ "d.m.Y" => "d.m.Y",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' mit dir geteilt. Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' kommentiert.<br/><br/><i>%s</i><br/><br/>Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hallo %s,<br/><br/><strong>%s</strong> hat an der Umfrage '%s' teilgenommen.<br/><br/>Um direkt zur Umfrage zu gelangen, kannst du diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" => "ownCloud Umfragen -- Neuer Kommentar",
+ "ownCloud Polls -- New Participant" => "ownCloud Umfragen -- Neuer Teilnehmer",
+ "ownCloud Polls -- New Poll" => "ownCloud Umfragen -- Neue Umfrage",
+ "ownCloud Polls" => "ownCloud Umfragen",
+ "Receive notification email on activity" => "Erhalte Emails bei Änderungen"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/l10n/de_DE.json b/l10n/de_DE.json
new file mode 100644
index 00000000..d0bb8986
--- /dev/null
+++ b/l10n/de_DE.json
@@ -0,0 +1,83 @@
+{ "translations": {
+ "Polls" : "Umfragen",
+ "Summary" : "Übersicht",
+ "No existing polls." : "Keine Umfragen vorhanden.",
+ "Title" : "Name",
+ "Description" : "Beschreibung",
+ "Please select at least one user or group!" : "Bitte wählen Sie mindestens einen Benutzer oder eine Gruppe aus!",
+ "Created" : "erstellt",
+ "Expires" : "Läuft ab",
+ "Never" : "Niemals",
+ "By" : "von",
+ "Go to" : "Gehe zu",
+ "Create new poll" : "Neue Umfrage erstellen",
+ "Access (click for link)" : "Zugriff (für Link klicken)",
+ "Access" : "Zugriff",
+ "Registered users only" : "Nur registrierte Benutzer",
+ "Public access" : "Öffentlicher Zugriff",
+ "hidden" : "versteckt",
+ "public" : "öffentlich",
+ "registered" : "für Registrierte",
+ "delete" : "löschen",
+ "Next" : "Weiter",
+ "Cancel" : "Abbrechen",
+ "Options" : "Optionen",
+ "Edit poll" : "Umfrage bearbeiten",
+ "Click on days to add or remove" : "Klicken Sie auf die Tage um sie hinzuzufügen oder zu löschen",
+ "Select hour & minute, then click on time" : "Wählen Sie Stunden und Minuten und klicken auf die Zeit",
+ "Mon" : "Mo",
+ "Tue" : "Di",
+ "Wed" : "Mi",
+ "Thu" : "Do",
+ "Fri" : "Fr",
+ "Sat" : "Sa",
+ "Sun" : "So",
+ "click to add" : "Zum Hinzufügen klicken",
+ "date\\time" : "Datum/Zeit",
+ "Poll URL" : "Umfrage-Link",
+ "Total" : "Gesamt",
+ "No description provided." : "Keine Beschreibung angegeben.",
+ "Write new Comment" : "Neuer Kommentar",
+ "Comments" : "Kommentare",
+ "No comments yet. Be the first." : "Bisher keine Kommentare. Sei der Erste.",
+ "Send!" : "Abschicken!",
+ "Vote!" : "Abstimmen!",
+ "Home" : "Startseite",
+ "participated" : "abgestimmt",
+ "Yourself" : "Ihnen",
+ "Select" : "Wählen",
+ "Close" : "Schließen",
+ "Users" : "Benutzer",
+ "Groups" : "Gruppen",
+ "Do you really want to delete that poll?" : "Sind Sie sicher, dass sie diese Umfrage löschen möchten?",
+ "You must enter at least a title for the new poll." : "Sie müssen zumindest einen Namen für die Umfrage angeben.",
+ "Copy to clipboard: Ctrl+C, Enter" : "In die Zwischenablage kopieren: Strg+C, Enter",
+ "Thanks that you've voted. You can close the page now." : "Danke, dass Sie abgestimmt haben. Sie können die Seite jetzt schließen.",
+ "Nothing selected!\nClick on cells to turn them green." : "Nichts ausgewählt!\nKlicken Sie auf die Elemente um sie auszuwählen (grün).",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "Sie sind nicht registriert.\nBitte geben Sie ihren Namen ein um abzustimmen\n(mindestens 3 Zeichen!)",
+ "You already have an item with the same text" : "Sie haben bereits ein Element mit dem gleichen Text.",
+ "Please choose the groups or users you want to add to your poll." : "Bitte wählen Sie die Gruppen oder Benutzer aus, die Sie zu ihrer Umfrage hinzufügen möchten.",
+ "Click to get link" : "Klicken Sie um den Link zu erhalten",
+ "Edit access" : "Zugriff ändern",
+ "Type" : "Art",
+ "Event schedule" : "Datumsangabe",
+ "Text based" : "Eigene Texte",
+ "Text item" : "Text",
+ "Dates" : "Termine",
+ "Description (will be shown as tooltip on the summary page)" : "Beschreibung (wird als Tooltip in der Übersicht angezeigt)",
+ "Poll expired" : "Umfrage abgelaufen",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "Die Umfrage lief am %s ab. Die Abstimmung ist geschlossen, aber es kann weiterhin kommentiert werden.",
+ "You are not allowed to view this poll or the poll does not exist." : "Ihnen fehlt die Berechtigung zur Anzeige dieser Abstimmung oder diese Abstimmung existiert nicht.",
+ "Error" : "Fehler",
+ "d.m.Y H:i" : "d.m.Y H:i",
+ "d.m.Y" : "d.m.Y",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' mit Ihnen geteilt. Um direkt zur Umfrage zu gelangen, können Sie diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat die Umfrage '%s' kommentiert.<br/><br/><i>%s</i><br/><br/>Um direkt zur Umfrage zu gelangen, können Sie diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hallo %s,<br/><br/><strong>%s</strong> hat an der Umfrage '%s' teilgenommen.<br/><br/>Um direkt zur Umfrage zu gelangen, können Sie diesen Link verwenden: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "ownCloud Umfragen -- Neuer Kommentar",
+ "ownCloud Polls -- New Participant" : "ownCloud Umfragen -- Neuer Teilnehmer",
+ "ownCloud Polls -- New Poll" : "ownCloud Umfragen -- Neue Umfrage",
+ "ownCloud Polls" : "ownCloud Umfragen",
+ "Receive notification email on activity" : "Erhalten Sie Emails bei Änderungen"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/en.json b/l10n/en.json
new file mode 100644
index 00000000..2c50fbe9
--- /dev/null
+++ b/l10n/en.json
@@ -0,0 +1,81 @@
+{ "translations": {
+ "Polls" : "Polls",
+ "Summary" : "Summary",
+ "No existing polls." : "No existing polls.",
+ "Title" : "Title",
+ "Description" : "Description",
+ "Please select at least one user or group!" : "Please select at least one user or group!",
+ "Created" : "Created",
+ "Expires" : "Expires",
+ "Never" : "Never",
+ "By" : "By",
+ "Go to" : "Go to",
+ "Create new poll" : "Create new poll",
+ "Access (click for link)" : "Access (click for link)",
+ "Access" : "Access",
+ "Registered users only" : "Registered users only",
+ "Public access" : "Public access",
+ "hidden" : "hidden",
+ "public" : "public",
+ "registered" : "registered",
+ "delete" : "delete",
+ "Next" : "Next",
+ "Cancel" : "Cancel",
+ "Options" : "Options",
+ "Edit poll" : "Edit poll",
+ "Click on days to add or remove" : "Click on days to add or remove",
+ "Select hour & minute, then click on time" : "Select hour & minute, then click on time",
+ "Mon" : "Mon",
+ "Tue" : "Tue",
+ "Wed" : "Wed",
+ "Thu" : "Thu",
+ "Fri" : "Fri",
+ "Sat" : "Sat",
+ "Sun" : "Sun",
+ "click to add" : "click to add",
+ "date\\time" : "date\\time",
+ "Poll URL" : "Poll URL",
+ "Total" : "Total",
+ "No description provided." : "No description provided.",
+ "Write new Comment" : "Write new Comment",
+ "Comments" : "Comments",
+ "No comments yet. Be the first." : "No comments yet. Be the first.",
+ "Send!" : "Send!",
+ "Vote!" : "Vote!",
+ "Home" : "Home",
+ "participated" : "participated",
+ "Yourself" : "Yourself",
+ "Select" : "Select",
+ "Close" : "Close",
+ "Users" : "Users",
+ "Groups" : "Groups",
+ "Do you really want to delete that poll?" : "Do you really want to delete that poll?",
+ "You must enter at least a title for the new poll." : "You must enter at least a title for the new poll.",
+ "Copy to clipboard: Ctrl+C, Enter" : "Copy to clipboard: Ctrl+C, Enter",
+ "Thanks that you've voted. You can close the page now." : "Thanks that you've voted. You can close the page now.",
+ "Nothing selected!\nClick on cells to turn them green." : "Nothing selected!\nClick on cells to turn them green.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)",
+ "You already have an item with the same text" : "You already have an item with the same text",
+ "Please choose the groups or users you want to add to your poll." : "Please choose the groups or users you want to add to your poll.",
+ "Click to get link" : "Click to get link",
+ "Edit access" : "Edit access",
+ "Type" : "Type",
+ "Event schedule" : "Event schedule",
+ "Text based" : "Text based",
+ "Text item" : "Text item",
+ "Dates" : "Dates",
+ "Description (will be shown as tooltip on the summary page)" : "Description (will be shown as tooltip on the summary page)",
+ "Poll expired" : "Poll expired",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "The poll expired on %s. Voting is disabled, but you can still comment.",
+ "You are not allowed to view this poll or the poll does not exist." : "You are not allowed to view this poll or the poll does not exist.",
+ "Error" : "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "ownCloud Polls -- New Comment",
+ "ownCloud Polls -- New Participant" : "ownCloud Polls -- New Participant",
+ "ownCloud Polls -- New Poll" : "ownCloud Polls -- New Poll",
+ "ownCloud Polls" : "ownCloud Polls",
+ "Receive notification email on activity" : "Receive notification email on activity"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/en.php b/l10n/en.php
new file mode 100644
index 00000000..44853637
--- /dev/null
+++ b/l10n/en.php
@@ -0,0 +1,82 @@
+<?php
+$TRANSLATIONS = array(
+ "Polls" => "Polls",
+ "Summary" => "Summary",
+ "No existing polls." => "No existing polls.",
+ "Title" => "Title",
+ "Description" => "Description",
+ "Please select at least one user or group!" : "Please select at least one user or group!",
+ "Created" => "Created",
+ "Expires" => "Expires",
+ "Never" => "Never",
+ "By" => "By",
+ "Go to" => "Go to",
+ "Create new poll" => "Create new poll",
+ "Access (click for link)" => "Access (click for link)",
+ "Access" => "Access",
+ "Registered users only" => "Registered users only",
+ "Public access" => "Public access",
+ "hidden" => "hidden",
+ "public" => "public",
+ "registered" => "registered",
+ "delete" => "delete",
+ "Next" => "Next",
+ "Cancel" => "Cancel",
+ "Options" => "Options",
+ "Edit poll" => "Edit poll",
+ "Click on days to add or remove" => "Click on days to add or remove",
+ "Select hour & minute, then click on time" => "Select hour & minute, then click on time",
+ "Mon" => "Mon",
+ "Tue" => "Tue",
+ "Wed" => "Wed",
+ "Thu" => "Thu",
+ "Fri" => "Fri",
+ "Sat" => "Sat",
+ "Sun" => "Sun",
+ "click to add" => "click to add",
+ "date\\time" => "date\\time",
+ "Poll URL" => "Poll URL",
+ "Total" => "Total",
+ "No description provided." => "No description provided.",
+ "Write new Comment" => "Write new Comment",
+ "Comments" => "Comments",
+ "No comments yet. Be the first." => "No comments yet. Be the first.",
+ "Send!" => "Send!",
+ "Vote!" => "Vote!",
+ "Home" => "Home",
+ "participated" => "participated",
+ "Yourself" => "Yourself",
+ "Select" => "Select",
+ "Close" => "Close",
+ "Users" => "Users",
+ "Groups" => "Groups",
+ "Do you really want to delete that poll?" => "Do you really want to delete that poll?",
+ "You must enter at least a title for the new poll." => "You must enter at least a title for the new poll.",
+ "Copy to clipboard: Ctrl+C, Enter" => "Copy to clipboard: Ctrl+C, Enter",
+ "Thanks that you've voted. You can close the page now." => "Thanks that you've voted. You can close the page now.",
+ "Nothing selected!\nClick on cells to turn them green." => "Nothing selected!\nClick on cells to turn them green.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" => "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)",
+ "You already have an item with the same text" => "You already have an item with the same text",
+ "Please choose the groups or users you want to add to your poll." => "Please choose the groups or users you want to add to your poll.",
+ "Click to get link" => "Click to get link",
+ "Edit access" => "Edit access",
+ "Type" => "Type",
+ "Event schedule" => "Event schedule",
+ "Text based" => "Text based",
+ "Text item" => "Text item",
+ "Dates" => "Dates",
+ "Description (will be shown as tooltip on the summary page)" => "Description (will be shown as tooltip on the summary page)",
+ "Poll expired" => "Poll expired",
+ "The poll expired on %s. Voting is disabled, but you can still comment." => "The poll expired on %s. Voting is disabled, but you can still comment.",
+ "You are not allowed to view this poll or the poll does not exist." => "You are not allowed to view this poll or the poll does not exist.",
+ "Error" => "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" => "ownCloud Polls -- New Comment",
+ "ownCloud Polls -- New Participant" => "ownCloud Polls -- New Participant",
+ "ownCloud Polls -- New Poll" => "ownCloud Polls -- New Poll",
+ "ownCloud Polls" => "ownCloud Polls",
+ "Receive notification email on activity" => "Receive notification email on activity"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/l10n/es.json b/l10n/es.json
new file mode 100644
index 00000000..4169a6c8
--- /dev/null
+++ b/l10n/es.json
@@ -0,0 +1,72 @@
+{ "translations": {
+ "Polls" : "Encuestas",
+ "Summary" : "Sumario",
+ "Title" : "Titulo",
+ "Description" : "Descripcion",
+ "Created" : "Creado",
+ "Expires" : "Expira",
+ "By" : "Por",
+ "Go to" : "Ir a",
+ "Create new poll" : "Crear nueva encuesta",
+ "Access (click for link)" : "Acceso (click para enlace)",
+ "Access" : "Acceso",
+ "Registered users only" : "Usuarios registrados solamente",
+ "Public access" : "Publico",
+ "hidden" : "oculto",
+ "public" : "publico",
+ "registered" : "registrado",
+ "delete" : "borrado",
+ "Next" : "Siguiente",
+ "Click on days to add or remove" : "Clicks en dias para agregar o remover",
+ "Select hour & minute, then click on time" : "Selecciona hora & minuto, sobre la fecha",
+ "Mon" : "Lun",
+ "Tue" : "Mar",
+ "Wed" : "Mie",
+ "Thu" : "Jue",
+ "Fri" : "Vie",
+ "Sat" : "Sab",
+ "Sun" : "Dom",
+ "click to add" : "click para agregar",
+ "date\\time" : "fecha\\hora",
+ "poll URL" : "encuesta URL",
+ "Total" : "Total",
+ "Comment" : "Commentario",
+ "Comments" : "Commentarios",
+ "Send" : "Enviar",
+ "Vote!" : "Votar!",
+ "Home" : "Inicio",
+ "participated" : "participado",
+ "Yourself" : "Ud mismo",
+ "Select" : "Seleccion",
+ "Close" : "Cerrado",
+ "Users" : "Usuarios",
+ "Groups" : "Grupos",
+ "Are you sure you want to delete this poll" : "Esta seguro que quiere borrar esta encuesta",
+ "You must enter at least a title for the new poll." : "Debe ingresar al menos un titulo para la nueva encuesta.",
+ "Copy to clipboard: Ctrl+C, Enter" : "copiar al portapapeles: Ctrl+C, Enter",
+ "Thanks that you've voted. You can close the page now." : "Gracias que ud ya voto. Puede ahora cerrar la pagina.",
+ "Nothing selected!\nClick on cells to turn them green." : "Nada seleccionado!\nClick en las celdas para ponerlas verdes.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "No eres usuario interno.\nPor favor usa tu usuario para votar\n(al menos 3 caracteres!)",
+ "You already have an item with the same text" : "Ya tienes un objeto con el mismo texto",
+ "Please choose the groups or users you want to add to your poll." : "Por favor escoge los grupos de usuarios que habilitaras la encuesta.",
+ "Click to get link" : "Click para obtener enlace",
+ "Edit access" : "Editar acceso",
+ "Type" : "Tipo",
+ "Event schedule" : "Programar evento",
+ "Text based" : "Base de texto",
+ "Text item" : "Item de texto",
+ "Description (will be shown as tooltip on the summary page)" : "Descripcion (sera mostrado como una ayuda en el resumen)",
+ "Poll expired" : "Encuesta expirado",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "La encuesta expiro en %s. Votos han terminado, pero se puede dejar comentarios.",
+ "You are not allowed to view this poll or the poll does not exist." : "No estas permitido para ver esta encuesta o la encuesta no existe.",
+ "Error" : "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s,<br/><br/><strong>%s</strong> compartio la votacion '%s' contigo. Para ir directo a la encuesta, puedes ir a este enlace: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s,<br/><br/><strong>%s</strong> comento en la votacion '%s'.<br/><br/><i>%s</i><br/><br/> Para ir directo a la encuesta, puedes usar este enlace: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Hola %s,<br/><br/><strong>%s</strong> participo en la votacion '%s'.<br/><br/> Para ir directo a la encuesta, puedes usar este enlace: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "ownCloud Encuestas -- Nuevo comentario",
+ "ownCloud Polls -- New Participant" : "ownCloud Encuestas -- Nuevo Participante",
+ "ownCloud Polls -- New Poll" : "ownCloud Encuestas -- Nueva encuesta",
+ "ownCloud Polls" : "Encuestas ownCloud",
+ "Receive notification email on activity" : "Recivir notificaciones de correos de las actividades"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/es.php b/l10n/es.php
new file mode 100644
index 00000000..3efc35a4
--- /dev/null
+++ b/l10n/es.php
@@ -0,0 +1,73 @@
+<?php
+$TRANSLATIONS = array(
+ "Polls" => "Encuestas",
+ "Summary" => "Sumario",
+ "Title" => "Titulo",
+ "Description" => "Descripcion",
+ "Created" => "Creado",
+ "Expires" => "Expira",
+ "By" => "Por",
+ "Go to" => "Ir a",
+ "Create new poll" => "Crear nueva encuesta",
+ "Access (click for link)" => "Acceso (click para enlace)",
+ "Access" => "Acceso",
+ "Registered users only" => "Usuarios registrados solamente",
+ "Public access" => "Publico",
+ "hidden" => "oculto",
+ "public" => "publico",
+ "registered" => "registrado",
+ "delete" => "borrado",
+ "Next" => "Siguiente",
+ "Click on days to add or remove" => "Clicks en dias para agregar o remover",
+ "Select hour & minute, then click on time" => "Selecciona hora & minuto, sobre la fecha",
+ "Mon" => "Lun",
+ "Tue" => "Mar",
+ "Wed" => "Mie",
+ "Thu" => "Jue",
+ "Fri" => "Vie",
+ "Sat" => "Sab",
+ "Sun" => "Dom",
+ "click to add" => "click para agregar",
+ "date\\time" => "fecha\\hora",
+ "poll URL" => "encuesta URL",
+ "Total" => "Total",
+ "Comment" => "Commentario",
+ "Comments" => "Commentarios",
+ "Send" => "Enviar",
+ "Vote!" => "Votar!",
+ "Home" => "Inicio",
+ "participated" => "participado",
+ "Yourself" => "Ud mismo",
+ "Select" => "Seleccion",
+ "Close" => "Cerrado",
+ "Users" => "Usuarios",
+ "Groups" => "Grupos",
+ "Are you sure you want to delete this poll" => "Esta seguro que quiere borrar esta encuesta",
+ "You must enter at least a title for the new poll." => "Debe ingresar al menos un titulo para la nueva encuesta.",
+ "Copy to clipboard: Ctrl+C, Enter" => "copiar al portapapeles: Ctrl+C, Enter",
+ "Thanks that you've voted. You can close the page now." => "Gracias que ud ya voto. Puede ahora cerrar la pagina.",
+ "Nothing selected!\nClick on cells to turn them green." => "Nada seleccionado!\nClick en las celdas para ponerlas verdes.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" => "No eres usuario interno.\nPor favor usa tu usuario para votar\n(al menos 3 caracteres!)",
+ "You already have an item with the same text" => "Ya tienes un objeto con el mismo texto",
+ "Please choose the groups or users you want to add to your poll." => "Por favor escoge los grupos de usuarios que habilitaras la encuesta.",
+ "Click to get link" => "Click para obtener enlace",
+ "Edit access" => "Editar acceso",
+ "Type" => "Tipo",
+ "Event schedule" => "Programar evento",
+ "Text based" => "Base de texto",
+ "Text item" => "Item de texto",
+ "Description (will be shown as tooltip on the summary page)" => "Descripcion (sera mostrado como una ayuda en el resumen)",
+ "Poll expired" => "Encuesta expirado",
+ "The poll expired on %s. Voting is disabled, but you can still comment." => "La encuesta expiro en %s. Votos han terminado, pero se puede dejar comentarios.",
+ "You are not allowed to view this poll or the poll does not exist." => "No estas permitido para ver esta encuesta o la encuesta no existe.",
+ "Error" => "Error",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s,<br/><br/><strong>%s</strong> compartio la votacion '%s' contigo. Para ir directo a la encuesta, puedes ir a este enlace: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s,<br/><br/><strong>%s</strong> comento en la votacion '%s'.<br/><br/><i>%s</i><br/><br/> Para ir directo a la encuesta, puedes usar este enlace: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Hola %s,<br/><br/><strong>%s</strong> participo en la votacion '%s'.<br/><br/> Para ir directo a la encuesta, puedes usar este enlace: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" => "ownCloud Encuestas -- Nuevo comentario",
+ "ownCloud Polls -- New Participant" => "ownCloud Encuestas -- Nuevo Participante",
+ "ownCloud Polls -- New Poll" => "ownCloud Encuestas -- Nueva encuesta",
+ "ownCloud Polls" => "Encuestas ownCloud",
+ "Receive notification email on activity" => "Recivir notificaciones de correos de las actividades"
+);
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/l10n/fr.json b/l10n/fr.json
new file mode 100644
index 00000000..065b3980
--- /dev/null
+++ b/l10n/fr.json
@@ -0,0 +1,72 @@
+{ "translations": {
+ "Polls" : "Sondages",
+ "Summary" : "Résumé",
+ "Title" : "Titre",
+ "Description" : "Description",
+ "Created" : "Créé",
+ "Expires" : "Expire",
+ "By" : "Par",
+ "Go to" : "Aller à",
+ "Create new poll" : "Créer un nouveau sondage",
+ "Access (click for link)" : "Accès (Cliquer pour le lien)",
+ "Access" : "Accès",
+ "Registered users only" : "Utilisateurs enregistrés uniquement",
+ "Public access" : "Accès Public",
+ "hidden" : "caché",
+ "public" : "public",
+ "registered" : "enregistré",
+ "delete" : "effacer",
+ "Next" : "Suivant",
+ "Click on days to add or remove" : "Sélectionner des dates en cliquant dessus pour les ajouter ou les supprimer",
+ "Select hour & minute, then click on time" : "Sélectionner l'heure et les minutes puis cliquer sur le résultat",
+ "Mon" : "Lu",
+ "Tue" : "Ma",
+ "Wed" : "Me",
+ "Thu" : "Je",
+ "Fri" : "Ve",
+ "Sat" : "Sa",
+ "Sun" : "Di",
+ "click to add" : "cliquer pour ajouter",
+ "date\\time" : "date\\heure",
+ "poll URL" : "lien du sondage",
+ "Total" : "Total",
+ "Comment" : "Commentaire",
+ "Comments" : "Commentaires",
+ "Send" : "Envoyer",
+ "Vote!" : "Voter!",
+ "Home" : "Accueil",
+ "participated" : "Participation",
+ "Yourself" : "Vous-même",
+ "Select" : "Choisir",
+ "Close" : "Fermer",
+ "Users" : "Utilisateurs",
+ "Groups" : "Groupes",
+ "Are you sure you want to delete this poll" : "Etes-vous sure de vouloir supprimer ce sondage",
+ "You must enter at least a title for the new poll." : "Vous devez au moins indiquer un titre pour ce nouveau sondage.",
+ "Copy to clipboard: Ctrl+C, Enter" : "Copier dans le presse papier: Control+C, Entrer",
+ "Thanks that you've voted. You can close the page now." : "Merci d'avoir voté. Vous pouvez maintenant fermer cette page.",
+ "Nothing selected!\nClick on cells to turn them green." : "Vous n'avez rien sélectionné\nCliquez sur un champ pour le passer en surbrillance.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" : "Vous n'êtes pas enregistré.\nIndiquez un nom pour voter\n(au moins 3 caractères!)",
+ "You already have an item with the same text" : "Vous avez déjà un champ avec le même texte.",
+ "Please choose the groups or users you want to add to your poll." : "Choisissez les groupes ou les utilisateurs que vous voulez ajouter au sondage.",
+ "Click to get link" : "Cliquez pour obtenir le lien",
+ "Edit access" : "Edition",
+ "Type" : "Type",
+ "Event schedule" : "Calendrier",
+ "Text based" : "Textuel",
+ "Text item" : "Texte",
+ "Description (will be shown as tooltip on the summary page)" : "Description (sera affichée dans une infobulle sur la page de résumé)",
+ "Poll expired" : "Sondage expiré",
+ "The poll expired on %s. Voting is disabled, but you can still comment." : "Ce sondage a expiré le %s. Les votes sont clos mais vous pouvez toujours ajouter des commentaires.",
+ "You are not allowed to view this poll or the poll does not exist." : "Vous n'êtes pas autorisé à voir ce sondage ou bien ce vote n'existe pas.",
+ "Error" : "Erreur",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Bonjour %s,<br/><br/><strong>%s</strong> a partagé le sondage '%s' avec vous. Pour répondre au sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Bonjour %s,<br/><br/><strong>%s</strong> a commenté le sondage '%s'.<br/><br/><i>%s</i><br/><br/>Pour voir le sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" : "Bonjour %s,<br/><br/><strong>%s</strong> a répondu au sondage '%s'.<br/><br/>Pour voir le sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" : "Sondages ownCloud -- Nouveau Commentaire",
+ "ownCloud Polls -- New Participant" : "Sondages ownCloud -- Nouveau Participant",
+ "ownCloud Polls -- New Poll" : "Sondages ownCloud -- Nouveau Sondage",
+ "ownCloud Polls" : "Sondages ownCloud",
+ "Receive notification email on activity" : "Recevoir un mail de notification pour toute activitée"
+},"pluralForm" :"nplurals=2; plural=(n != 1);"
+}
diff --git a/l10n/fr.php b/l10n/fr.php
new file mode 100644
index 00000000..a6ca1f77
--- /dev/null
+++ b/l10n/fr.php
@@ -0,0 +1,73 @@
+<?php
+$TRANSLATIONS = array(
+ "Polls" => "Sondages",
+ "Summary" => "Résumé",
+ "Title" => "Titre",
+ "Description" => "Description",
+ "Created" => "Créé",
+ "Expires" => "Expire",
+ "By" => "Par",
+ "Go to" => "Aller à",
+ "Create new poll" => "Créer un nouveau sondage",
+ "Access (click for link)" => "Accès (Cliquer pour le lien)",
+ "Access" => "Accès",
+ "Registered users only" => "Utilisateurs enregistrés uniquement",
+ "Public access" => "Accès Public",
+ "hidden" => "caché",
+ "public" => "public",
+ "registered" => "enregistré",
+ "delete" => "effacer",
+ "Next" => "Suivant",
+ "Click on days to add or remove" => "Sélectionner des dates en cliquant dessus pour les ajouter ou les supprimer",
+ "Select hour & minute, then click on time" => "Sélectionner l'heure et les minutes puis cliquer sur le résultat",
+ "Mon" => "Lu",
+ "Tue" => "Ma",
+ "Wed" => "Me",
+ "Thu" => "Je",
+ "Fri" => "Ve",
+ "Sat" => "Sa",
+ "Sun" => "Di",
+ "click to add" => "cliquer pour ajouter",
+ "date\\time" => "date\\heure",
+ "poll URL" => "lien du sondage",
+ "Total" => "Total",
+ "Comment" => "Commentaire",
+ "Comments" => "Commentaires",
+ "Send" => "Envoyer",
+ "Vote!" => "Voter!",
+ "Home" => "Accueil",
+ "participated" => "Participation",
+ "Yourself" => "Vous-même",
+ "Select" => "Choisir",
+ "Close" => "Fermer",
+ "Users" => "Utilisateurs",
+ "Groups" => "Groupes",
+ "Are you sure you want to delete this poll" => "Etes-vous sure de vouloir supprimer ce sondage",
+ "You must enter at least a title for the new poll." => "Vous devez au moins indiquer un titre pour ce nouveau sondage.",
+ "Copy to clipboard: Ctrl+C, Enter" => "Copier dans le presse papier: Control+C, Entrer",
+ "Thanks that you've voted. You can close the page now." => "Merci d'avoir voté. Vous pouvez maintenant fermer cette page.",
+ "Nothing selected!\nClick on cells to turn them green." => "Vous n'avez rien sélectionné\nCliquez sur un champ pour le passer en surbrillance.",
+ "You are not registered.\nPlease enter your name to vote\n(at least 3 characters!)" => "Vous n'êtes pas enregistré.\nIndiquez un nom pour voter\n(au moins 3 caractères!)",
+ "You already have an item with the same text" => "Vous avez déjà un champ avec le même texte.",
+ "Please choose the groups or users you want to add to your poll." => "Choisissez les groupes ou les utilisateurs que vous voulez ajouter au sondage.",
+ "Click to get link" => "Cliquez pour obtenir le lien",
+ "Edit access" => "Edition",
+ "Type" => "Type",
+ "Event schedule" => "Calendrier",
+ "Text based" => "Textuel",
+ "Text item" => "Texte",
+ "Description (will be shown as tooltip on the summary page)" => "Description (sera affichée dans une infobulle sur la page de résumé)",
+ "Poll expired" => "Sondage expiré",
+ "The poll expired on %s. Voting is disabled, but you can still comment." => "Ce sondage a expiré le %s. Les votes sont clos mais vous pouvez toujours ajouter des commentaires.",
+ "You are not allowed to view this poll or the poll does not exist." => "Vous n'êtes pas autorisé à voir ce sondage ou bien ce vote n'existe pas.",
+ "Error" => "Erreur",
+ "Hello %s,<br/><br/><strong>%s</strong> shared the poll '%s' with you. To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Bonjour %s,<br/><br/><strong>%s</strong> a partagé le sondage '%s' avec vous. Pour répondre au sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> commented on the poll '%s'.<br/><br/><i>%s</i><br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Bonjour %s,<br/><br/><strong>%s</strong> a commenté le sondage '%s'.<br/><br/><i>%s</i><br/><br/>Pour voir le sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "Hello %s,<br/><br/><strong>%s</strong> participated in the poll '%s'.<br/><br/>To go directly to the poll, you can use this link: <a href=\"%s\">%s</a>" => "Bonjour %s,<br/><br/><strong>%s</strong> a répondu au sondage '%s'.<br/><br/>Pour voir le sondage, utilisez ce lien: <a href=\"%s\">%s</a>",
+ "ownCloud Polls -- New Comment" => "Sondages ownCloud -- Nouveau Commentaire",
+ "ownCloud Polls -- New Participant" => "Sondages ownCloud -- Nouveau Participant",
+ "ownCloud Polls -- New Poll" => "Sondages ownCloud -- Nouveau Sondage",
+ "ownCloud Polls" => "Sondages ownCloud",
+ "Receive notification email on activity" => "Recevoir un mail de notification pour toute activitée"
+ );
+$PLURAL_FORMS = "nplurals=2; plural=(n != 1);";
diff --git a/templates/create.tmpl.php b/templates/create.tmpl.php
new file mode 100644
index 00000000..9854b201
--- /dev/null
+++ b/templates/create.tmpl.php
@@ -0,0 +1,161 @@
+<?php
+ \OCP\Util::addStyle('polls', 'main');
+ \OCP\Util::addStyle('polls', 'jquery.datetimepicker');
+ \OCP\Util::addScript('polls', 'create_edit');
+ \OCP\Util::addScript('polls', 'jquery.datetimepicker.full.min');
+ $userId = $_['userId'];
+ $userMgr = $_['userMgr'];
+ $urlGenerator = $_['urlGenerator'];
+ $isUpdate = isset($_['poll']) && $_['poll'] !== null;
+ if($isUpdate) {
+ $poll = $_['poll'];
+ $dates = $_['dates'];
+ $chosen = '[';
+ foreach($dates as $d) {
+ if($poll->getType() === '0') $chosen .= strtotime($d->getDt());
+ else $chosen .= $d->getText();
+ $chosen .= ',';
+ }
+ $chosen = trim($chosen, ',');
+ $chosen .= ']';
+ $title = $poll->getTitle();
+ $desc = $poll->getDescription();
+ if($poll->getExpire() !== null) $expireTs = strtotime($poll->getExpire()) - 60*60*24; //remove one day, which has been added to expire at the end of a day
+ $expireStr = date('d.m.Y', $expireTs);
+ $access = $poll->getAccess();
+ $accessTypes = $access;
+ if($access !== 'registered' && $access !== 'hidden' && $access !== 'public') $access = 'select';
+ }
+?>
+
+<?php if($isUpdate): ?>
+<form name="finish_poll" action="<?php p($urlGenerator->linkToRoute('polls.page.update_poll', null, true)); ?>" method="POST">
+ <input type="hidden" name="pollId" value="<?php p($poll->getId()); ?>" />
+<?php else: ?>
+<form name="finish_poll" action="<?php p($urlGenerator->linkToRoute('polls.page.insert_poll', null, true)); ?>" method="POST">
+<?php endif; ?>
+ <input type="hidden" name="chosenDates" id="chosenDates" value="<?php if(isset($chosen)) p($chosen); ?>" />
+ <input type="hidden" name="expireTs" id="expireTs" value="<?php if(isset($expireTs)) p($expireTs); ?>" />
+ <input type="hidden" name="userId" id="userId" value="<?php p($userId); ?>" />
+
+ <div class="new_poll">
+ <?php if($isUpdate): ?>
+ <h1><?php p($l->t('Edit poll') . ' ' . $poll->getTitle()); ?></h1>
+ <?php else: ?>
+ <h1><?php p($l->t('Create new poll')); ?></h1>
+ <?php endif; ?>
+ <label for="text_title" class="label_h1 input_title"><?php p($l->t('Title')); ?></label>
+ <input type="text" class="input_field" id="pollTitle" name="pollTitle" value="<?php if(isset($title)) p($title); ?>" />
+ <label for="pollDesc" class="label_h1 input_title"><?php p($l->t('Description')); ?></label>
+ <textarea cols="50" rows="5" style="width: auto;" class="input_field" id="pollDesc" name="pollDesc" value="<?php if(isset($desc)) p($desc); ?>"></textarea>
+
+ <div class="input_title"><?php p($l->t('Access')); ?></div>
+
+ <input type="radio" name="accessType" id="private" value="registered" <?php if(!$isUpdate || $access === 'registered') print_unescaped('checked'); ?> />
+ <label for="private"><?php p($l->t('Registered users only')); ?></label>
+
+ <input type="radio" name="accessType" id="hidden" value="hidden" <?php if($isUpdate && $access === 'hidden') print_unescaped('checked'); ?> />
+ <label for="hidden"><?php p($l->t('hidden')); ?></label>
+
+ <input type="radio" name="accessType" id="public" value="public" <?php if($isUpdate && $access === 'public') print_unescaped('checked'); ?> />
+ <label for="public"><?php p($l->t('Public access')); ?></label>
+
+ <input type="radio" name="accessType" id="select" value="select" <?php if($isUpdate && $access === 'select') print_unescaped('checked'); ?>>
+ <label for="select"><?php p($l->t('Select')); ?></label>
+ <span id="id_label_select">...</span>
+
+ <input type="hidden" name="accessValues" id="accessValues" value="<?php if($isUpdate && $access === 'select') p($accessTypes) ?>" />
+
+ <div class="input_title"><?php p($l->t('Type')); ?></div>
+
+ <input type="radio" name="pollType" id="event" value="event" <?php if(!$isUpdate || $poll->getType() === '0') print_unescaped('checked'); ?> />
+ <label for="event"><?php p($l->t('Event schedule')); ?></label>
+
+ <!-- TODO texts to db -->
+ <input type="radio" name="pollType" id="text" value="text" <?php if($isUpdate && $poll->getType() === '1') print_unescaped('checked'); ?>>
+ <label for="text"><?php p($l->t('Text based')); ?></label>
+
+ <br/>
+ <input id="id_expire_set" name="check_expire" type="checkbox" <?php ($isUpdate && $poll->getExpire() !== null) ? print_unescaped('value="true" checked') : print_unescaped('value="false"'); ?> />
+ <label for="id_expire_set"><?php p($l->t('Expires')); ?>:</label>
+ <input id="id_expire_date" type="text" required="" <?php (!$isUpdate || $poll->getExpire() === null) ? print_unescaped('disabled="true"') : print_unescaped('value="' . $expireStr . '"'); ?> name="expire_date_input" />
+ <br/>
+ <div id="date-select-container">
+ <label for="datetimepicker"><?php p($l->t('Dates')); ?>:</label>
+ <br/>
+ <input id="datetimepicker" type="text" />
+
+ <table id="selected-dates-table">
+ </table>
+ </div>
+ <div id="text-select-container" style="display:none;">
+ <label for="text-title"><?php p($l->t('Text item')); ?>:</label>
+ <input type="text" id="text-title" placeholder="<?php print_unescaped('Insert text...'); ?>" />
+ <br/>
+ <input type="button" id="text-submit" value="<?php p($l->t('Add')); ?>"/>
+ <table id="selected-texts-table">
+ </table>
+ </div>
+
+ <br/>
+ <a href="<?php p($urlGenerator->linkToRoute('polls.page.index', null, true)); ?>"><input type="button" id="submit_cancel_poll" value="<?php p($l->t('Cancel')); ?>" /></a>
+ <input type="submit" id="submit_finish_poll" value="<?php p($l->t('Next')); ?>" />
+ </div>
+</form>
+
+<div id="dialog-box">
+ <div id="dialog-message"></div>
+ <?php if (isset($url)) : ?>
+ <input type="radio" name="radio_pub" id="private" value="registered"/>
+ <label for="private"><?php p($l->t('Registered users only')); ?></label>
+ <br/>
+ <input type="radio" name="radio_pub" id="hidden" value="hidden" />
+ <label for="hidden"><?php p($l->t('hidden')); ?></label>
+ <br/>
+ <input type="radio" name="radio_pub" id="public" value="public" />
+ <label for="public"><?php p($l->t('Public access')); ?></label>
+ <br/>
+ <input type="radio" name="radio_pub" id="select" value="select" checked />
+ <label for="select"><?php p($l->t('Select')); ?></label>
+ <br/>
+ <?php endif; ?>
+
+ <table id="table_access">
+ <tr>
+ <td>
+ <div class="scroll_div_dialog">
+ <table id="table_groups">
+ <tr>
+ <th><?php p($l->t('Groups')); ?></th>
+ </tr>
+ <?php $groups = OC_Group::getUserGroups($userId); ?>
+ <?php foreach($groups as $gid) : ?>
+ <tr>
+ <td class="cl_group_item"><?php p($gid); ?></td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ </div>
+ </td>
+ <td>
+ <div class="scroll_div_dialog">
+ <table id="table_users">
+ <tr>
+ <th><?php p($l->t('Users')); ?></th>
+ </tr>
+ <?php $users = $userMgr->search(''); ?>
+ <?php foreach ($users as $user) : ?>
+ <tr>
+ <td class="cl_user_item" id="user_<?php p($user->getUID()); ?>" >
+ <?php p($user->getDisplayName()); ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ </div>
+ </td>
+ </tr>
+ </table>
+ <input type="button" id="button_cancel_access" value="<?php p($l->t('Cancel')); ?>" />
+ <input type="button" id="button_ok_access" value="<?php p($l->t('Ok')); ?>" />
+</div>
diff --git a/templates/goto.tmpl.php b/templates/goto.tmpl.php
new file mode 100644
index 00000000..8e0d5690
--- /dev/null
+++ b/templates/goto.tmpl.php
@@ -0,0 +1,382 @@
+<?php
+\OCP\Util::addStyle('polls', 'main');
+\OCP\Util::addScript('polls', 'vote');
+
+$userId = $_['userId'];
+$userMgr = $_['userMgr'];
+$urlGenerator = $_['urlGenerator'];
+use \OCP\User;
+
+$poll = $_['poll'];
+$dates = $_['dates'];
+$votes = $_['votes'];
+$comments = $_['comments'];
+$poll_type = $poll->getType();
+if ($poll->getExpire() === null) $expired = false;
+else {
+ $expired = time() > strtotime($poll->getExpire());
+}
+
+if ($poll->getType() === '0') {
+ // count how many times in each date
+ $arr_dates = null; // will be like: [21.02] => 3
+ $arr_years = null; // [1992] => 6
+ foreach($dates as $d) {
+ $date = date('d.m.Y', strtotime($d->getDt()));
+ $arr = explode('.', $date);
+ $day_month = $arr[0] . '.' . $arr[1] . '.'; // 21.02
+ $year = $arr[2]; // 1992
+
+ if (isset($arr_dates[$day_month])) {
+ $arr_dates[$day_month] += 1;
+ } else {
+ $arr_dates[$day_month] = 1;
+ }
+
+ // -----
+ if (isset($arr_years[$year])) {
+ $arr_years[$year] += 1;
+ } else {
+ $arr_years[$year] = 1;
+ }
+
+ }
+
+ $for_string_dates = '';
+ foreach (array_keys($arr_dates) as $dt) { // date (13.09)
+ $for_string_dates .= '<th colspan="' . $arr_dates[$dt] . '">' . $dt . '</th>';
+ }
+
+ $for_string_years = '';
+ foreach (array_keys($arr_years) as $year) { // year (1992)
+ $for_string_years .= '<th colspan="' . $arr_years[$year] . '">' . $year . '</th>';
+ }
+
+}
+if($poll->getDescription() !== null && $poll->getDescription() !== '') $line = str_replace("\n", '<br/>', $poll->getDescription());
+else $line = $l->t('No description provided.');
+
+// ----------- title / descr --------
+?>
+<!-- TODO reimplement?
+<?php if(!User::isLoggedIn()) : ?>
+ <p>
+ <header>
+ <div id="header">
+ <a href="<?php print_unescaped(link_to('', 'index.php')); ?>"
+ title="" id="owncloud">
+ <div class="logo-wide svg"></div>
+ </a>
+ <div id="logo-claim" style="display:none;"><?php p($theme->getLogoClaim()); ?></div>
+ <div class="header-right">
+ <?php p($l->t('Already have an account?')); ?>
+ <?php $url = OCP\Util::linkToAbsolute( '', 'index.php' ).'?redirect_url='.$urlGenerator->linkToRoute('polls_goto', array('poll_id' => $poll_id)); ?>
+ <a href="<?php p($url); ?>"><?php p($l->t('Login')); ?></a>
+ </div>
+ </div>
+ </header>
+ </p>
+ <p>&nbsp;</p><p>&nbsp;</p> <?php // for some reason the header covers the title otherwise ?>
+<?php endif; ?>
+-->
+
+
+<h1><?php p($poll->getTitle()); ?></h1>
+<div class="wordwrap desc"><?php p($line); ?></div>
+
+<?
+// -------------- url ---------------
+
+?>
+<h2><?php p($l->t('Poll URL')); ?></h2>
+<p class="url">
+ <?php
+ $url = $urlGenerator->linkToRoute('polls.page.goto_poll', ['hash' => $poll->getHash()], true);
+ //$url = $urlGenerator->getAbsoluteURL($url);
+ ?>
+ <a href="<?php p($url);?>"><?php p($url); ?></a>
+</p>
+
+
+<div class="scroll_div">
+ <table class="vote_table" id="id_table_1"> <?php //from above title ?>
+ <tr>
+ <th></th>
+ <?php
+ if ($poll_type === '0') {
+ print_unescaped($for_string_years);
+ }
+ else {
+ foreach ($dates as $el) {
+ print_unescaped('<th title="' . $el->getText(). '">' . $el->getText() . '</th>');
+ }
+ }
+ ?>
+ </tr>
+ <?php
+ if ($poll_type === '0'){
+ print_unescaped('<tr><th></th>' . $for_string_dates . '</tr>');
+
+ print_unescaped('<tr><th></th>');
+ for ($i = 0; $i < count($chosen); $i++) {
+ $ch_obj = date('H:i', strtotime($chosen[$i]));
+ print_unescaped('<th>' . $ch_obj . '</th>');
+ }
+ print_unescaped('</tr>');
+ }
+
+ // init array for counting 'yes'-votes for each dt
+ $total_y = array();
+ $total_n = array();
+ for ($i = 0; $i < count($dates); $i++){
+ $total_y[$i] = 0;
+ $total_n[$i] = 0;
+ }
+ $user_voted = array();
+ // -------------- other users ---------------
+ // loop over users
+ ?>
+ <?php
+ if ($votes !== null) {
+ //group by user
+ $others = array();
+ foreach ($votes as $vote) {
+ if (!isset($others[$vote->getUserId()])) {
+ $others[$vote->getUserId()] = array();
+ }
+ array_push($others[$vote->getUserId()], $vote);
+ }
+ foreach (array_keys($others) as $usr) {
+ if ($usr === $userId) {
+ // if poll expired, just put current user among the others;
+ // otherwise skip here to add current user as last row (to vote)
+ if (!$expired) {
+ $user_voted = $others[$usr];
+ continue;
+ }
+ }
+ print_unescaped('<tr>');
+ print_unescaped('<th>' . $userMgr->get($usr)->getDisplayName() . '</th>');
+ $i_tot = -1;
+
+ // loop over dts
+ foreach($dates as $dt) {
+ $i_tot++;
+
+ $date_id = '';
+ if ($poll_type === '0') {
+ $date_id = strtotime($dt->getDt());
+ }
+ else {
+ $date_id = $dt->getText();
+ }
+ // look what user voted for this dts
+ $found = false;
+ foreach ($others[$usr] as $vote) {
+ if ($date_id === strtotime($vote->getDt())) {
+ if ($vote->getType() === '1') {
+ $cl = 'poll-cell-is icon-checkmark';
+ $total_y[$i_tot]++;
+ }
+ else if ($vote->getType() === '0') {
+ $cl = 'poll-cell-not icon-close';
+ $total_n[$i_tot]++;
+ } else {
+ $cl = 'poll-cell-maybe icon-more';
+ }
+ $found = true;
+ break;
+ }
+ }
+ if(!$found) {
+ $cl = 'poll-cell-un icon-info';
+ }
+ print_unescaped('<td class="' . $cl . '"></td>');
+ }
+ print_unescaped('</tr>');
+ }
+ }
+ // -------------- current user --------------
+ ?>
+ <tr>
+ <?php
+ if (!$expired) {
+ if (User::isLoggedIn()) {
+ print_unescaped('<th>' . $userMgr->get($userId)->getDisplayName() . '</th>');
+ } else {
+ print_unescaped('<th id="id_ac_detected" ><input type="text" name="user_name" id="user_name" /></th>');
+ }
+ $i_tot = -1;
+ $date_id = '';
+ foreach ($dates as $dt) {
+ $i_tot++;
+ if ($poll_type === '0') {
+ $date_id = strtotime($dt->getDt());
+ } else {
+ $date_id = $dt->getText();
+ }
+ // see if user already has data for this event
+ $cl = 'poll-cell-active-un icon-info';
+ if (isset($user_voted)) {
+ foreach ($user_voted as $obj) {
+ $voteVal = null;
+ if($poll_type === '0') $voteVal = strtotime($obj->getDt());
+ else $voteVal = $obj->getText();
+ if ($voteVal === $date_id) {
+ if ($obj->getType() === '1') {
+ $cl = 'poll-cell-active-is icon-checkmark';
+ $total_y[$i_tot]++;
+ } else if ($obj->getType() === '0') {
+ $cl = 'poll-cell-active-not icon-close';
+ $total_n[$i_tot]++;
+ } else if($obj->getType() === '2'){
+ //$total_m[$i_tot]++;
+ $cl = 'poll-cell-active-maybe icon-more';
+ }
+ break;
+ }
+ }
+ }
+ print_unescaped('<td class="cl_click ' . $cl . '" id="' . $date_id . '"></td>');
+ }
+ }
+ ?>
+ </tr>
+ <?php // --------------- total -------------------- ?>
+ <?php
+ $diff_array = $total_y;
+ for($i = 0; $i < count($diff_array); $i++){
+ $diff_array[$i] = ($total_y[$i] - $total_n[$i]);
+ }
+ $max_votes = max($diff_array);
+ ?>
+ <tr>
+ <th><?php p($l->t('Total')); ?>:</th>
+ <?php for ($i = 0; $i < count($dates); $i++) : ?>
+ <td>
+ <?php if($poll_type === '0'): ?>
+ <table id="id_tab_total">
+ <tr>
+ <td id="id_y_<?php p(strtotime($dates[$i]->getDt())); ?>"
+ <?php if(isset($total_y[$i])) : ?>
+ <?php if( $total_y[$i] - $total_n[$i] === $max_votes) : ?>
+ <?php
+ $class = 'cl_total_y cl_win';
+ ?>
+ <?php else : ?>
+ <?php $class='cl_total_y'; ?>
+ <?php endif; ?>
+ <?php $val = $total_y[$i]; ?>
+ <?php else : ?>
+ <?php $val = 0; ?>
+ <?php endif; ?>
+ class="<?php p($class); ?>"><?php p($val); ?>
+ </td>
+ </tr>
+ <tr>
+ <td id="id_n_<?php p(strtotime($dates[$i]->getDt())); ?>" class="cl_total_n"><?php p(isset($total_n[$i]) ? $total_n[$i] : '0'); ?></td>
+ </tr>
+ </table>
+ <?php endif; ?>
+ </td>
+ <?php endfor; ?>
+ </tr>
+
+ <?php // ------------ winner ----------------------- ?>
+ <tr>
+ <th><?php p($l->t('Win:')); ?></th>
+ <?php for ($i = 0; $i < count($dates); $i++) :
+
+ $check = '';
+ if ($total_y[$i] - $total_n[$i] === $max_votes){
+ $check = 'icon-checkmark';
+ }
+
+ print_unescaped('<td class="win_row ' . $check . '" id="id_total_' . $i . '"></td>');
+
+ endfor;
+ ?>
+ </tr>
+ <?php
+ if ($poll_type === '0'){
+ print_unescaped('<tr><td></td>');
+ for ($i = 0; $i < count($dates); $i++) {
+ $ch_obj = date('H:i', strtotime($dates[$i]->getDt()));
+ print_unescaped('<th>' . $ch_obj . '</th>');
+ }
+ print_unescaped('</tr>');
+ print_unescaped('<tr><td></td>' . $for_string_dates . '</tr>');
+ }
+ ?>
+ <tr>
+ <?php
+ if ($poll_type === '0') {
+ print_unescaped('<th>' . $for_string_years . '</th>');
+ }
+ else {
+ foreach ($chosen as $el) {
+ print_unescaped('<th title="' . $el->desc . '">' . $el->dt . '</th>');
+ }
+ }
+ ?>
+ </tr>
+ </table>
+</div>
+
+<?php if(User::isLoggedIn()) : ?>
+ <input type="checkbox" id="check_notif" <?php if($notification !== null) print_unescaped(' checked'); ?> />
+ <label for="check_notif"><?php p($l->t('Receive notification email on activity')); ?></label>
+ <br/>
+<?php endif; ?>
+
+<a href="<?php p($urlGenerator->linkToRoute('polls.page.index', null, true)); ?>" style="float:left;padding-right: 5px;"><input type="button" class="icon-home" /></a>
+<form name="finish_vote" action="<?php p($urlGenerator->linkToRoute('polls.page.insert_vote', null, true)); ?>" method="POST">
+ <input type="hidden" name="pollId" value="<?php p($poll->getId()); ?>" />
+ <input type="hidden" name="userId" value="<?php p($userId); ?>" />
+ <input type="hidden" name="dates" value="<?php p($poll->getId()); ?>" />
+ <input type="hidden" name="types" value="<?php p($poll->getId()); ?>" />
+ <input type="hidden" name="notif" />
+ <input type="hidden" name="changed" />
+ <input type="button" id="submit_finish_vote" value="<?php p($l->t('Vote!')); ?>" />
+</form>
+
+
+<?php if($expired) : ?>
+<div id="expired_info">
+ <h2><?php p($l->t('Poll expired')); ?></h2>
+ <p>
+ <?php p($l->t('The poll expired on %s. Voting is disabled, but you can still comment.', array(date('d.m.Y H:i', strtotime($poll->getExpire()))))); ?>
+ </p>
+</div>
+<?php endif; ?>
+
+<?php // -------- comments ---------- ?>
+<h2><?php p($l->t('Comments')); ?></h2>
+<div class="cl_user_comments">
+ <?php if($comments !== null) : ?>
+ <?php foreach ($comments as $comment) : ?>
+ <div class="user_comment">
+ <?php
+ p($userMgr->get($comment->getUserId())->getDisplayName());
+ print_unescaped(' <i class="date">' . date('d.m.Y H:i', strtotime($comment->getDt())) . '</i>');
+ ?>
+ <div class="wordwrap user_comment_text">
+ <?php p($comment->getComment()); ?>
+ </div>
+ </div>
+ <?php endforeach; ?>
+ <?php else : ?>
+ <?php p($l->t('No comments yet. Be the first.')); ?>
+ <?php endif; ?>
+ <div class="cl_comment">
+ <form name="send_comment" action="<?php p($urlGenerator->linkToRoute('polls.page.insert_comment', null, true)); ?>" method="POST">
+ <input type="hidden" name="pollId" value="<?php p($poll->getId()); ?>" />
+ <input type="hidden" name="userId" value="<?php p($userId); ?>" />
+ <?php // -------- leave comment ---------- ?>
+ <h3><?php p($l->t('Write new Comment')); ?></h3>
+ <textarea style="width: 300px;" cols="50" rows="3" id="commentBox" name="commentBox"></textarea>
+ <br/>
+ <input type="button" id="submit_send_comment" value="<?php p($l->t('Send!')); ?>" />
+ </form>
+ </div>
+</div>
diff --git a/templates/main.tmpl.php b/templates/main.tmpl.php
new file mode 100644
index 00000000..adaf63f6
--- /dev/null
+++ b/templates/main.tmpl.php
@@ -0,0 +1,142 @@
+<?php
+ \OCP\Util::addStyle('polls', 'main');
+ \OCP\Util::addScript('polls', 'start');
+ use OCP\User;
+ $userId = $_['userId'];
+ $userMgr = $_['userMgr'];
+ $urlGenerator = $_['urlGenerator'];
+?>
+
+<h1><?php p($l->t('Summary')); ?></h1>
+<div class="goto_poll">
+ <?php
+ $url = $urlGenerator->linkToRoute('polls.page.index');
+ ?>
+ <?php if(count($_['polls']) === 0) : ?>
+ <?php p($l->t('No existing polls.')); ?>
+ <?php else : ?>
+ <table class="cl_create_form">
+ <tr>
+ <th><?php p($l->t('Title')); ?></th>
+ <th id="id_th_descr"><?php p($l->t('Description')); ?></th>
+ <th><?php p($l->t('Created')); ?></th>
+ <th><?php p($l->t('By')); ?></th>
+ <th><?php p($l->t('Expires')); ?></th>
+ <th><?php p($l->t('participated')); ?></th>
+ <th id="id_th_descr"><?php p($l->t('Access')); ?></th>
+ <th><?php p($l->t('Options')); ?></th>
+ </tr>
+ <?php foreach ($_['polls'] as $poll) : ?>
+ <?php
+ if (!userHasAccess($poll)) continue;
+ // direct url to poll
+ $pollUrl = $url . 'goto/' . $poll->getHash();
+ ?>
+ <tr>
+ <td title="<?php p($l->t('Go to')); ?>">
+ <a class="table_link" href="<?php p($pollUrl); ?>"><?php p($poll->getTitle()); ?></a>
+ </td>
+ <?php
+ $desc_str = $poll->getDescription();
+ if($desc_str === null) $desc_str = $l->t('No description provided.');
+ if (strlen($desc_str) > 100){
+ $desc_str = substr($desc_str, 0, 80) . '...';
+ }
+ ?>
+ <td><?php p($desc_str); ?></td>
+ <td class="cl_poll_url" title="<?php p($l->t('Click to get link')); ?>"><input type="hidden" value="<?php p($pollUrl); ?>" /><?php p(date('d.m.Y H:i', strtotime($poll->getCreated()))); ?></td>
+ <td>
+ <?php
+ if($poll->getOwner() === $userId) p($l->t('Yourself'));
+ else p($userMgr->get($poll->getOwner()));
+ ?>
+ </td>
+ <?php
+ if ($poll->getExpire() !== null) {
+ $style = '';
+ if (date('U') > strtotime($poll->getExpire())) {
+ $style = ' style="color: red"';
+ }
+ print_unescaped('<td' . $style . '>' . date('d.m.Y', strtotime($poll->getExpire())) . '</td>');
+ }
+ else {
+ print_unescaped('<td>' . $l->t('Never') . '</td>');
+ }
+ ?>
+ <td>
+ <?php
+ $partic_class = 'partic_no';
+ $partic_polls = $_['participations'];
+ for($i = 0; $i < count($partic_polls); $i++){
+ if($poll->getId() == intval($partic_polls[$i]->getPollId())){
+ $partic_class = 'partic_yes';
+ array_splice($partic_polls, $i, 1);
+ break;
+ }
+ }
+ ?>
+ <div class="partic_all <?php p($partic_class); ?>">
+ </div>
+ |
+ <?php
+ $partic_class = 'partic_no';
+ $partic_comm = $_['comments'];
+ for($i = 0; $i < count($partic_comm); $i++){
+ if($poll->getId() === intval($partic_comm[$i]->getPollId())){
+ $partic_class = 'partic_yes';
+ array_splice($partic_comm, $i, 1);
+ break;
+ }
+ }
+ ?>
+ <div class="partic_all <?php p($partic_class); ?>">
+ </div>
+ </td>
+ <td <?php if ($poll->getOwner() === $userId) print_unescaped('class="cl_poll_access" id="cl_poll_access_' . $poll->getId() . '" title="'.$l->t('Edit access').'"'); ?> >
+ <?php p($l->t($poll->getAccess())); ?>
+ </td>
+ <td>
+ <?php if ($poll->getOwner() === $userId) : ?>
+ <input type="button" id="id_del_<?php p($poll->getId()); ?>" class="table_button cl_delete icon-delete"></input>
+ <a href="<?php p($urlGenerator->linkToRoute('polls.page.edit_poll', ['hash' => $poll->getHash()], true)); ?>"><input type="button" id="id_edit_<?php p($poll->getId()); ?>" class="table_button cl_edit icon-rename"></input></a>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ <form id="form_delete_poll" name="form_delete_poll" action="<?php p($urlGenerator->linkToRoute('polls.page.delete_poll', null, true)); ?>" method="POST">
+ </form>
+ <?php endif; ?>
+</div>
+<a href="<?php p($urlGenerator->linkToRoute('polls.page.create_poll', null, true)); ?>"><input type="button" id="submit_new_poll" class="icon-add" /></a>
+
+<?php
+// ---- helper functions ----
+ function userHasAccess($poll) {
+ if($poll === null) return false;
+ $access = $poll->getAccess();
+ $owner = $poll->getOwner();
+ if (!User::isLoggedIn()) return false;
+ if ($access === 'public') return true;
+ if ($access === 'hidden') return true;
+ if ($access === 'registered') return true;
+ if ($owner === $userId) return true;
+ $user_groups = OC_Group::getUserGroups($userId);
+
+ $arr = explode(';', $access);
+
+ foreach ($arr as $item) {
+ if (strpos($item, 'group_') === 0) {
+ $grp = substr($item, 6);
+ foreach ($user_groups as $user_group) {
+ if ($user_group === $grp) return true;
+ }
+ }
+ else if (strpos($item, 'user_') === 0) {
+ $usr = substr($item, 5);
+ if ($usr === $userId) return true;
+ }
+ }
+ return false;
+ }
+?>
diff --git a/templates/no.acc.tmpl.php b/templates/no.acc.tmpl.php
new file mode 100644
index 00000000..012b5c10
--- /dev/null
+++ b/templates/no.acc.tmpl.php
@@ -0,0 +1,13 @@
+<?php
+ \OCP\Util::addStyle('polls', 'main');
+?>
+<h1>
+ <center>
+ <?php p($l->t('Error')); ?>
+ </center>
+</h1>
+<h2>
+ <center>
+ <?php p($l->t('You are not allowed to view this poll or the poll does not exist.')); ?>
+ </center>
+</h2>