From 530e7f03cd2a5c8b348408cb33ea14a424c48f49 Mon Sep 17 00:00:00 2001 From: Michael Gapczynski Date: Mon, 30 Jul 2012 10:34:12 -0400 Subject: [PATCH] Remove accidently added 3rd party apps --- apps/journal/.gitignore | 51 - apps/journal/COPYING-AGPL | 661 ---- apps/journal/COPYING-README | 10 - apps/journal/Changelog | 5 - apps/journal/README.md | 38 - apps/journal/TODO | 13 - .../journal/ajax/categories/categoriesfor.php | 28 - apps/journal/ajax/categories/delete.php | 54 - apps/journal/ajax/categories/list.php | 17 - apps/journal/ajax/categories/rescan.php | 42 - apps/journal/ajax/delete.php | 37 - apps/journal/ajax/entries.php | 36 - apps/journal/ajax/saveproperty.php | 138 - apps/journal/ajax/setdefaultcalendar.php | 36 - apps/journal/ajax/util.php | 40 - apps/journal/appinfo/app.php | 18 - apps/journal/appinfo/info.xml | 11 - apps/journal/css/journal.css | 19 - apps/journal/css/rte.css | 7 - apps/journal/img/bold.svg | 11 - apps/journal/img/indent-less.svg | 300 -- apps/journal/img/indent-more.svg | 295 -- apps/journal/img/italic.svg | 8 - apps/journal/img/journal.png | Bin 581 -> 0 bytes apps/journal/img/journal.svg | 104 - apps/journal/img/justify-center.svg | 269 -- apps/journal/img/justify-fill.svg | 269 -- apps/journal/img/justify-left.svg | 199 - apps/journal/img/justify-right.svg | 269 -- apps/journal/img/list.svg | 12 - apps/journal/img/strikethrough.svg | 10 - apps/journal/img/underline.svg | 10 - apps/journal/index.php | 72 - apps/journal/js/expanding.js | 118 - apps/journal/js/journal.js | 432 --- apps/journal/js/jquery.rte.js | 244 -- apps/journal/js/jquery.textchange.js | 76 - apps/journal/js/settings.js | 15 - apps/journal/lib/app.php | 135 - apps/journal/lib/hooks.php | 53 - apps/journal/lib/search.php | 45 - apps/journal/lib/vjournal.php | 27 - apps/journal/settings.php | 45 - apps/journal/templates/index.pt | 101 - apps/journal/templates/rtfm.php | 7 - apps/journal/templates/settings.pt | 15 - apps/news/.gitignore | 5 - apps/news/ajax/createfeed.php | 37 - apps/news/ajax/createfolder.php | 41 - apps/news/ajax/deletefeed.php | 33 - apps/news/ajax/deletefolder.php | 33 - apps/news/ajax/feeddialog.php | 7 - apps/news/ajax/folderdialog.php | 7 - apps/news/ajax/markitem.php | 35 - apps/news/ajax/populateroot.php | 18 - apps/news/appinfo/app.php | 42 - apps/news/appinfo/database.xml | 186 - apps/news/appinfo/info.xml | 10 - apps/news/css/news.css | 52 - apps/news/index.php | 44 - apps/news/js/news.js | 196 - apps/news/js/settings.js | 15 - apps/news/lib/collection.php | 32 - apps/news/lib/feed.php | 46 - apps/news/lib/feedmapper.php | 182 - apps/news/lib/folder.php | 56 - apps/news/lib/foldermapper.php | 148 - apps/news/lib/item.php | 122 - apps/news/lib/itemmapper.php | 171 - apps/news/lib/utils.php | 46 - apps/news/settings.php | 8 - apps/news/templates/main.php | 36 - apps/news/templates/part.addfeed.php | 22 - apps/news/templates/part.addfolder.php | 22 - apps/news/templates/part.feeds.php | 31 - apps/news/templates/part.folderlist.php | 12 - apps/news/templates/part.items.php | 23 - apps/news/templates/part.nofeeds.php | 3 - apps/news/templates/settings.php | 8 - apps/news/templates/test.php | 85 - apps/shorty/.htaccess | 45 - .../shorty/3rdparty/js/jquery.tinysort.min.js | 1 - apps/shorty/3rdparty/php/phpqrcode.php | 3312 ----------------- apps/shorty/ajax/add.php | 101 - apps/shorty/ajax/click.php | 67 - apps/shorty/ajax/count.php | 54 - apps/shorty/ajax/del.php | 63 - apps/shorty/ajax/edit.php | 88 - apps/shorty/ajax/list.php | 77 - apps/shorty/ajax/meta.php | 56 - apps/shorty/ajax/preferences.php | 119 - apps/shorty/ajax/settings.php | 109 - apps/shorty/ajax/status.php | 67 - apps/shorty/appinfo/app.php | 53 - apps/shorty/appinfo/database.xml | 148 - apps/shorty/appinfo/info.xml | 56 - apps/shorty/appinfo/migrate.php | 101 - apps/shorty/css/preferences.css | 109 - apps/shorty/css/settings.css | 59 - apps/shorty/css/shorty.css | 488 --- apps/shorty/doc/CHANGELOG | 59 - apps/shorty/doc/CONFIGURATION | 113 - apps/shorty/doc/COPYRIGHT | 23 - apps/shorty/doc/CREDITS | 32 - apps/shorty/doc/INSTALLATION | 53 - apps/shorty/doc/ISSUES | 58 - apps/shorty/doc/README | 42 - apps/shorty/doc/ROADMAP | 96 - apps/shorty/doc/STATUS | 42 - apps/shorty/doc/USAGE | 64 - apps/shorty/img/actions/down.png | Bin 250 -> 0 bytes apps/shorty/img/actions/down.svg | 9 - apps/shorty/img/actions/external.png | Bin 421 -> 0 bytes apps/shorty/img/actions/external.svg | 11 - apps/shorty/img/actions/info.png | Bin 297 -> 0 bytes apps/shorty/img/actions/info.svg | 70 - apps/shorty/img/actions/left.png | Bin 221 -> 0 bytes apps/shorty/img/actions/left.svg | 9 - apps/shorty/img/actions/minus.png | Bin 288 -> 0 bytes apps/shorty/img/actions/open.png | Bin 320 -> 0 bytes apps/shorty/img/actions/open.svg | 10 - apps/shorty/img/actions/plus.png | Bin 297 -> 0 bytes apps/shorty/img/actions/recycle.png | Bin 751 -> 0 bytes apps/shorty/img/actions/recycle.svg | 93 - apps/shorty/img/actions/reload.png | Bin 1083 -> 0 bytes apps/shorty/img/actions/right.png | Bin 220 -> 0 bytes apps/shorty/img/actions/right.svg | 9 - apps/shorty/img/actions/shade.png | Bin 434 -> 0 bytes apps/shorty/img/actions/shade.svg | 78 - apps/shorty/img/actions/up.png | Bin 235 -> 0 bytes apps/shorty/img/actions/up.svg | 9 - apps/shorty/img/blank.png | Bin 219 -> 0 bytes apps/shorty/img/calendar.png | Bin 659 -> 0 bytes apps/shorty/img/drag_me.png | Bin 5189 -> 0 bytes apps/shorty/img/drag_me.svg | 135 - apps/shorty/img/loading-bar.gif | Bin 1190 -> 0 bytes apps/shorty/img/loading-disk.gif | Bin 6894 -> 0 bytes apps/shorty/img/loading-led.gif | Bin 684 -> 0 bytes apps/shorty/img/scheme/A.png | Bin 973 -> 0 bytes apps/shorty/img/scheme/B.png | Bin 1111 -> 0 bytes apps/shorty/img/scheme/C.png | Bin 978 -> 0 bytes apps/shorty/img/scheme/D.png | Bin 1035 -> 0 bytes apps/shorty/img/scheme/E.png | Bin 988 -> 0 bytes apps/shorty/img/scheme/F.png | Bin 969 -> 0 bytes apps/shorty/img/scheme/G.png | Bin 995 -> 0 bytes apps/shorty/img/scheme/H.png | Bin 991 -> 0 bytes apps/shorty/img/scheme/J.png | Bin 935 -> 0 bytes apps/shorty/img/scheme/K.png | Bin 980 -> 0 bytes apps/shorty/img/scheme/L.png | Bin 910 -> 0 bytes apps/shorty/img/scheme/M.png | Bin 985 -> 0 bytes apps/shorty/img/scheme/N.png | Bin 996 -> 0 bytes apps/shorty/img/scheme/O.png | Bin 1016 -> 0 bytes apps/shorty/img/scheme/P.png | Bin 950 -> 0 bytes apps/shorty/img/scheme/Q.png | Bin 1041 -> 0 bytes apps/shorty/img/scheme/R.png | Bin 983 -> 0 bytes apps/shorty/img/scheme/S.png | Bin 950 -> 0 bytes apps/shorty/img/scheme/T.png | Bin 904 -> 0 bytes apps/shorty/img/scheme/U.png | Bin 977 -> 0 bytes apps/shorty/img/scheme/V.png | Bin 967 -> 0 bytes apps/shorty/img/scheme/W.png | Bin 1026 -> 0 bytes apps/shorty/img/scheme/X.png | Bin 959 -> 0 bytes apps/shorty/img/scheme/Y.png | Bin 927 -> 0 bytes apps/shorty/img/scheme/Z.png | Bin 956 -> 0 bytes apps/shorty/img/shorty.png | Bin 746 -> 0 bytes apps/shorty/img/shorty.svg | 11 - apps/shorty/img/status/active.png | Bin 485 -> 0 bytes apps/shorty/img/status/active.svg | 9 - apps/shorty/img/status/bad.png | Bin 795 -> 0 bytes apps/shorty/img/status/good.png | Bin 794 -> 0 bytes apps/shorty/img/status/neutral.png | Bin 763 -> 0 bytes apps/shorty/img/status/strike.png | Bin 355 -> 0 bytes apps/shorty/img/usage/64/arrow.png | Bin 3309 -> 0 bytes apps/shorty/img/usage/64/clipboard.png | Bin 3402 -> 0 bytes apps/shorty/img/usage/64/email.png | Bin 4302 -> 0 bytes apps/shorty/img/usage/64/globe.png | Bin 5242 -> 0 bytes apps/shorty/img/usage/64/home.png | Bin 4009 -> 0 bytes apps/shorty/img/usage/64/info.png | Bin 2817 -> 0 bytes apps/shorty/img/usage/64/locked.png | Bin 3091 -> 0 bytes apps/shorty/img/usage/64/network.png | Bin 3451 -> 0 bytes apps/shorty/img/usage/64/qrcode.png | Bin 6373 -> 0 bytes apps/shorty/img/usage/64/sms.png | Bin 3700 -> 0 bytes apps/shorty/img/usage/64/team.png | Bin 3539 -> 0 bytes apps/shorty/img/usage/64/unlocked.png | Bin 3115 -> 0 bytes apps/shorty/img/usage/64/workstation.png | Bin 3218 -> 0 bytes apps/shorty/img/usage/_.svg | 19 - apps/shorty/img/usage/arrow.svg | 22 - apps/shorty/img/usage/clipboard.svg | 34 - apps/shorty/img/usage/email.svg | 21 - apps/shorty/img/usage/globe.svg | 19 - apps/shorty/img/usage/home.svg | 23 - apps/shorty/img/usage/info.svg | 21 - apps/shorty/img/usage/locked.svg | 23 - apps/shorty/img/usage/network.svg | 34 - apps/shorty/img/usage/qrcode.svg | 271 -- apps/shorty/img/usage/sms.svg | 19 - apps/shorty/img/usage/team.svg | 20 - apps/shorty/img/usage/unlocked.svg | 23 - apps/shorty/img/usage/workstation.svg | 22 - apps/shorty/index.php | 149 - apps/shorty/js/add.js | 51 - apps/shorty/js/debug.js | 71 - apps/shorty/js/init.js | 92 - apps/shorty/js/list.js | 39 - apps/shorty/js/preferences.js | 69 - apps/shorty/js/settings.js | 53 - apps/shorty/js/shorty.js | 1489 -------- apps/shorty/l10n/de.php | 157 - apps/shorty/lib/backend.php | 286 -- apps/shorty/lib/exception.php | 162 - apps/shorty/lib/hooks.php | 64 - apps/shorty/lib/l10n.php | 93 - apps/shorty/lib/meta.php | 213 -- apps/shorty/lib/query.php | 57 - apps/shorty/lib/tools.php | 235 -- apps/shorty/lib/type.php | 291 -- apps/shorty/preferences.php | 68 - apps/shorty/qrcode.php | 100 - apps/shorty/relay.php | 140 - apps/shorty/settings.php | 52 - apps/shorty/templates/tmpl_dlg_qrcode.php | 52 - apps/shorty/templates/tmpl_dlg_verify.php | 70 - apps/shorty/templates/tmpl_http_status.php | 41 - apps/shorty/templates/tmpl_index.php | 66 - apps/shorty/templates/tmpl_preferences.php | 257 -- apps/shorty/templates/tmpl_settings.php | 70 - apps/shorty/templates/tmpl_url_add.php | 86 - apps/shorty/templates/tmpl_url_edit.php | 100 - apps/shorty/templates/tmpl_url_list.php | 167 - apps/shorty/templates/tmpl_url_share.php | 89 - apps/shorty/templates/tmpl_url_show.php | 85 - apps/storage_charts/ajax/config.php | 44 - apps/storage_charts/ajax/data.php | 37 - apps/storage_charts/appinfo/app.php | 51 - apps/storage_charts/appinfo/app_admin.php | 58 - apps/storage_charts/appinfo/database.xml | 99 - apps/storage_charts/appinfo/info.xml | 11 - apps/storage_charts/charts.php | 46 - apps/storage_charts/css/styles.css | 32 - apps/storage_charts/img/chart.png | Bin 441 -> 0 bytes apps/storage_charts/img/loader.gif | Bin 1849 -> 0 bytes apps/storage_charts/img/move.png | Bin 457 -> 0 bytes .../js/highCharts-2.2.1/highcharts.min.js | 202 - apps/storage_charts/js/units.min.js | 23 - apps/storage_charts/l10n/de.php | 58 - apps/storage_charts/l10n/en.php | 58 - apps/storage_charts/l10n/fr.php | 58 - apps/storage_charts/l10n/pt_BR.php | 59 - apps/storage_charts/lib/db.class.php | 290 -- apps/storage_charts/lib/loader.class.php | 102 - apps/storage_charts/settings.php | 43 - apps/storage_charts/templates/charts.tpl.php | 77 - .../storage_charts/templates/settings.tpl.php | 40 - apps/tal/.gitignore | 51 - apps/tal/COPYING-AGPL | 661 ---- apps/tal/COPYING-README | 10 - apps/tal/README.md | 26 - apps/tal/TODO | 2 - apps/tal/ajax/loadpage.php | 23 - apps/tal/appinfo/app.php | 11 - apps/tal/appinfo/info.xml | 11 - apps/tal/css/tal.css | 25 - apps/tal/index.php | 30 - apps/tal/js/modernizr.js | 1265 ------- apps/tal/js/tal.js | 32 - apps/tal/lib/paths.php | 13 - apps/tal/lib/tall10n.php | 105 - apps/tal/lib/taltemplate.php | 372 -- apps/tal/settings.php | 16 - apps/tal/templates/layout.guest.pt | 43 - apps/tal/templates/layout.user.pt | 78 - apps/tal/templates/macros.util.pt | 56 - apps/tal/templates/manual.pt | 23 - apps/tal/templates/sections.pt | 142 - apps/tal/templates/settings.pt | 10 - apps/tanghus-journal-2c506aa.tar.gz | Bin 41637 -> 0 bytes apps/tanghus-tal-7f8befe.tar.gz | Bin 37994 -> 0 bytes 276 files changed, 22402 deletions(-) delete mode 100644 apps/journal/.gitignore delete mode 100644 apps/journal/COPYING-AGPL delete mode 100644 apps/journal/COPYING-README delete mode 100644 apps/journal/Changelog delete mode 100644 apps/journal/README.md delete mode 100644 apps/journal/TODO delete mode 100644 apps/journal/ajax/categories/categoriesfor.php delete mode 100644 apps/journal/ajax/categories/delete.php delete mode 100644 apps/journal/ajax/categories/list.php delete mode 100644 apps/journal/ajax/categories/rescan.php delete mode 100644 apps/journal/ajax/delete.php delete mode 100644 apps/journal/ajax/entries.php delete mode 100644 apps/journal/ajax/saveproperty.php delete mode 100644 apps/journal/ajax/setdefaultcalendar.php delete mode 100644 apps/journal/ajax/util.php delete mode 100644 apps/journal/appinfo/app.php delete mode 100644 apps/journal/appinfo/info.xml delete mode 100644 apps/journal/css/journal.css delete mode 100644 apps/journal/css/rte.css delete mode 100644 apps/journal/img/bold.svg delete mode 100644 apps/journal/img/indent-less.svg delete mode 100644 apps/journal/img/indent-more.svg delete mode 100644 apps/journal/img/italic.svg delete mode 100644 apps/journal/img/journal.png delete mode 100644 apps/journal/img/journal.svg delete mode 100644 apps/journal/img/justify-center.svg delete mode 100644 apps/journal/img/justify-fill.svg delete mode 100644 apps/journal/img/justify-left.svg delete mode 100644 apps/journal/img/justify-right.svg delete mode 100644 apps/journal/img/list.svg delete mode 100644 apps/journal/img/strikethrough.svg delete mode 100644 apps/journal/img/underline.svg delete mode 100644 apps/journal/index.php delete mode 100644 apps/journal/js/expanding.js delete mode 100644 apps/journal/js/journal.js delete mode 100644 apps/journal/js/jquery.rte.js delete mode 100644 apps/journal/js/jquery.textchange.js delete mode 100644 apps/journal/js/settings.js delete mode 100644 apps/journal/lib/app.php delete mode 100644 apps/journal/lib/hooks.php delete mode 100644 apps/journal/lib/search.php delete mode 100644 apps/journal/lib/vjournal.php delete mode 100644 apps/journal/settings.php delete mode 100644 apps/journal/templates/index.pt delete mode 100644 apps/journal/templates/rtfm.php delete mode 100644 apps/journal/templates/settings.pt delete mode 100644 apps/news/.gitignore delete mode 100644 apps/news/ajax/createfeed.php delete mode 100644 apps/news/ajax/createfolder.php delete mode 100644 apps/news/ajax/deletefeed.php delete mode 100644 apps/news/ajax/deletefolder.php delete mode 100644 apps/news/ajax/feeddialog.php delete mode 100644 apps/news/ajax/folderdialog.php delete mode 100644 apps/news/ajax/markitem.php delete mode 100644 apps/news/ajax/populateroot.php delete mode 100644 apps/news/appinfo/app.php delete mode 100644 apps/news/appinfo/database.xml delete mode 100644 apps/news/appinfo/info.xml delete mode 100644 apps/news/css/news.css delete mode 100644 apps/news/index.php delete mode 100644 apps/news/js/news.js delete mode 100644 apps/news/js/settings.js delete mode 100644 apps/news/lib/collection.php delete mode 100644 apps/news/lib/feed.php delete mode 100644 apps/news/lib/feedmapper.php delete mode 100644 apps/news/lib/folder.php delete mode 100644 apps/news/lib/foldermapper.php delete mode 100644 apps/news/lib/item.php delete mode 100644 apps/news/lib/itemmapper.php delete mode 100644 apps/news/lib/utils.php delete mode 100644 apps/news/settings.php delete mode 100644 apps/news/templates/main.php delete mode 100644 apps/news/templates/part.addfeed.php delete mode 100644 apps/news/templates/part.addfolder.php delete mode 100644 apps/news/templates/part.feeds.php delete mode 100644 apps/news/templates/part.folderlist.php delete mode 100644 apps/news/templates/part.items.php delete mode 100644 apps/news/templates/part.nofeeds.php delete mode 100644 apps/news/templates/settings.php delete mode 100644 apps/news/templates/test.php delete mode 100644 apps/shorty/.htaccess delete mode 100644 apps/shorty/3rdparty/js/jquery.tinysort.min.js delete mode 100644 apps/shorty/3rdparty/php/phpqrcode.php delete mode 100644 apps/shorty/ajax/add.php delete mode 100644 apps/shorty/ajax/click.php delete mode 100644 apps/shorty/ajax/count.php delete mode 100644 apps/shorty/ajax/del.php delete mode 100644 apps/shorty/ajax/edit.php delete mode 100644 apps/shorty/ajax/list.php delete mode 100644 apps/shorty/ajax/meta.php delete mode 100644 apps/shorty/ajax/preferences.php delete mode 100644 apps/shorty/ajax/settings.php delete mode 100644 apps/shorty/ajax/status.php delete mode 100644 apps/shorty/appinfo/app.php delete mode 100644 apps/shorty/appinfo/database.xml delete mode 100644 apps/shorty/appinfo/info.xml delete mode 100644 apps/shorty/appinfo/migrate.php delete mode 100644 apps/shorty/css/preferences.css delete mode 100644 apps/shorty/css/settings.css delete mode 100644 apps/shorty/css/shorty.css delete mode 100644 apps/shorty/doc/CHANGELOG delete mode 100644 apps/shorty/doc/CONFIGURATION delete mode 100644 apps/shorty/doc/COPYRIGHT delete mode 100644 apps/shorty/doc/CREDITS delete mode 100644 apps/shorty/doc/INSTALLATION delete mode 100644 apps/shorty/doc/ISSUES delete mode 100644 apps/shorty/doc/README delete mode 100644 apps/shorty/doc/ROADMAP delete mode 100644 apps/shorty/doc/STATUS delete mode 100644 apps/shorty/doc/USAGE delete mode 100644 apps/shorty/img/actions/down.png delete mode 100644 apps/shorty/img/actions/down.svg delete mode 100644 apps/shorty/img/actions/external.png delete mode 100644 apps/shorty/img/actions/external.svg delete mode 100644 apps/shorty/img/actions/info.png delete mode 100644 apps/shorty/img/actions/info.svg delete mode 100644 apps/shorty/img/actions/left.png delete mode 100644 apps/shorty/img/actions/left.svg delete mode 100644 apps/shorty/img/actions/minus.png delete mode 100644 apps/shorty/img/actions/open.png delete mode 100644 apps/shorty/img/actions/open.svg delete mode 100644 apps/shorty/img/actions/plus.png delete mode 100644 apps/shorty/img/actions/recycle.png delete mode 100644 apps/shorty/img/actions/recycle.svg delete mode 100644 apps/shorty/img/actions/reload.png delete mode 100644 apps/shorty/img/actions/right.png delete mode 100644 apps/shorty/img/actions/right.svg delete mode 100644 apps/shorty/img/actions/shade.png delete mode 100644 apps/shorty/img/actions/shade.svg delete mode 100644 apps/shorty/img/actions/up.png delete mode 100644 apps/shorty/img/actions/up.svg delete mode 100644 apps/shorty/img/blank.png delete mode 100644 apps/shorty/img/calendar.png delete mode 100644 apps/shorty/img/drag_me.png delete mode 100644 apps/shorty/img/drag_me.svg delete mode 100644 apps/shorty/img/loading-bar.gif delete mode 100644 apps/shorty/img/loading-disk.gif delete mode 100644 apps/shorty/img/loading-led.gif delete mode 100644 apps/shorty/img/scheme/A.png delete mode 100644 apps/shorty/img/scheme/B.png delete mode 100644 apps/shorty/img/scheme/C.png delete mode 100644 apps/shorty/img/scheme/D.png delete mode 100644 apps/shorty/img/scheme/E.png delete mode 100644 apps/shorty/img/scheme/F.png delete mode 100644 apps/shorty/img/scheme/G.png delete mode 100644 apps/shorty/img/scheme/H.png delete mode 100644 apps/shorty/img/scheme/J.png delete mode 100644 apps/shorty/img/scheme/K.png delete mode 100644 apps/shorty/img/scheme/L.png delete mode 100644 apps/shorty/img/scheme/M.png delete mode 100644 apps/shorty/img/scheme/N.png delete mode 100644 apps/shorty/img/scheme/O.png delete mode 100644 apps/shorty/img/scheme/P.png delete mode 100644 apps/shorty/img/scheme/Q.png delete mode 100644 apps/shorty/img/scheme/R.png delete mode 100644 apps/shorty/img/scheme/S.png delete mode 100644 apps/shorty/img/scheme/T.png delete mode 100644 apps/shorty/img/scheme/U.png delete mode 100644 apps/shorty/img/scheme/V.png delete mode 100644 apps/shorty/img/scheme/W.png delete mode 100644 apps/shorty/img/scheme/X.png delete mode 100644 apps/shorty/img/scheme/Y.png delete mode 100644 apps/shorty/img/scheme/Z.png delete mode 100644 apps/shorty/img/shorty.png delete mode 100644 apps/shorty/img/shorty.svg delete mode 100644 apps/shorty/img/status/active.png delete mode 100644 apps/shorty/img/status/active.svg delete mode 100644 apps/shorty/img/status/bad.png delete mode 100644 apps/shorty/img/status/good.png delete mode 100644 apps/shorty/img/status/neutral.png delete mode 100644 apps/shorty/img/status/strike.png delete mode 100644 apps/shorty/img/usage/64/arrow.png delete mode 100644 apps/shorty/img/usage/64/clipboard.png delete mode 100644 apps/shorty/img/usage/64/email.png delete mode 100644 apps/shorty/img/usage/64/globe.png delete mode 100644 apps/shorty/img/usage/64/home.png delete mode 100644 apps/shorty/img/usage/64/info.png delete mode 100644 apps/shorty/img/usage/64/locked.png delete mode 100644 apps/shorty/img/usage/64/network.png delete mode 100644 apps/shorty/img/usage/64/qrcode.png delete mode 100644 apps/shorty/img/usage/64/sms.png delete mode 100644 apps/shorty/img/usage/64/team.png delete mode 100644 apps/shorty/img/usage/64/unlocked.png delete mode 100644 apps/shorty/img/usage/64/workstation.png delete mode 100644 apps/shorty/img/usage/_.svg delete mode 100644 apps/shorty/img/usage/arrow.svg delete mode 100644 apps/shorty/img/usage/clipboard.svg delete mode 100644 apps/shorty/img/usage/email.svg delete mode 100644 apps/shorty/img/usage/globe.svg delete mode 100644 apps/shorty/img/usage/home.svg delete mode 100644 apps/shorty/img/usage/info.svg delete mode 100644 apps/shorty/img/usage/locked.svg delete mode 100644 apps/shorty/img/usage/network.svg delete mode 100644 apps/shorty/img/usage/qrcode.svg delete mode 100644 apps/shorty/img/usage/sms.svg delete mode 100644 apps/shorty/img/usage/team.svg delete mode 100644 apps/shorty/img/usage/unlocked.svg delete mode 100644 apps/shorty/img/usage/workstation.svg delete mode 100644 apps/shorty/index.php delete mode 100644 apps/shorty/js/add.js delete mode 100644 apps/shorty/js/debug.js delete mode 100644 apps/shorty/js/init.js delete mode 100644 apps/shorty/js/list.js delete mode 100644 apps/shorty/js/preferences.js delete mode 100644 apps/shorty/js/settings.js delete mode 100644 apps/shorty/js/shorty.js delete mode 100644 apps/shorty/l10n/de.php delete mode 100644 apps/shorty/lib/backend.php delete mode 100644 apps/shorty/lib/exception.php delete mode 100644 apps/shorty/lib/hooks.php delete mode 100644 apps/shorty/lib/l10n.php delete mode 100644 apps/shorty/lib/meta.php delete mode 100644 apps/shorty/lib/query.php delete mode 100644 apps/shorty/lib/tools.php delete mode 100644 apps/shorty/lib/type.php delete mode 100644 apps/shorty/preferences.php delete mode 100644 apps/shorty/qrcode.php delete mode 100644 apps/shorty/relay.php delete mode 100644 apps/shorty/settings.php delete mode 100644 apps/shorty/templates/tmpl_dlg_qrcode.php delete mode 100644 apps/shorty/templates/tmpl_dlg_verify.php delete mode 100644 apps/shorty/templates/tmpl_http_status.php delete mode 100644 apps/shorty/templates/tmpl_index.php delete mode 100644 apps/shorty/templates/tmpl_preferences.php delete mode 100644 apps/shorty/templates/tmpl_settings.php delete mode 100644 apps/shorty/templates/tmpl_url_add.php delete mode 100644 apps/shorty/templates/tmpl_url_edit.php delete mode 100644 apps/shorty/templates/tmpl_url_list.php delete mode 100644 apps/shorty/templates/tmpl_url_share.php delete mode 100644 apps/shorty/templates/tmpl_url_show.php delete mode 100644 apps/storage_charts/ajax/config.php delete mode 100644 apps/storage_charts/ajax/data.php delete mode 100644 apps/storage_charts/appinfo/app.php delete mode 100644 apps/storage_charts/appinfo/app_admin.php delete mode 100644 apps/storage_charts/appinfo/database.xml delete mode 100644 apps/storage_charts/appinfo/info.xml delete mode 100644 apps/storage_charts/charts.php delete mode 100644 apps/storage_charts/css/styles.css delete mode 100644 apps/storage_charts/img/chart.png delete mode 100644 apps/storage_charts/img/loader.gif delete mode 100644 apps/storage_charts/img/move.png delete mode 100644 apps/storage_charts/js/highCharts-2.2.1/highcharts.min.js delete mode 100644 apps/storage_charts/js/units.min.js delete mode 100644 apps/storage_charts/l10n/de.php delete mode 100644 apps/storage_charts/l10n/en.php delete mode 100644 apps/storage_charts/l10n/fr.php delete mode 100644 apps/storage_charts/l10n/pt_BR.php delete mode 100644 apps/storage_charts/lib/db.class.php delete mode 100644 apps/storage_charts/lib/loader.class.php delete mode 100644 apps/storage_charts/settings.php delete mode 100644 apps/storage_charts/templates/charts.tpl.php delete mode 100644 apps/storage_charts/templates/settings.tpl.php delete mode 100644 apps/tal/.gitignore delete mode 100644 apps/tal/COPYING-AGPL delete mode 100644 apps/tal/COPYING-README delete mode 100644 apps/tal/README.md delete mode 100644 apps/tal/TODO delete mode 100644 apps/tal/ajax/loadpage.php delete mode 100644 apps/tal/appinfo/app.php delete mode 100644 apps/tal/appinfo/info.xml delete mode 100644 apps/tal/css/tal.css delete mode 100644 apps/tal/index.php delete mode 100644 apps/tal/js/modernizr.js delete mode 100644 apps/tal/js/tal.js delete mode 100644 apps/tal/lib/paths.php delete mode 100644 apps/tal/lib/tall10n.php delete mode 100644 apps/tal/lib/taltemplate.php delete mode 100644 apps/tal/settings.php delete mode 100644 apps/tal/templates/layout.guest.pt delete mode 100644 apps/tal/templates/layout.user.pt delete mode 100644 apps/tal/templates/macros.util.pt delete mode 100644 apps/tal/templates/manual.pt delete mode 100644 apps/tal/templates/sections.pt delete mode 100644 apps/tal/templates/settings.pt delete mode 100644 apps/tanghus-journal-2c506aa.tar.gz delete mode 100644 apps/tanghus-tal-7f8befe.tar.gz diff --git a/apps/journal/.gitignore b/apps/journal/.gitignore deleted file mode 100644 index e2ff07d14d..0000000000 --- a/apps/journal/.gitignore +++ /dev/null @@ -1,51 +0,0 @@ -# the default generated dir + db file -data -owncloud -config/config.php -config/mount.php -apps/inc.php - -# just sane ignores -.*.sw[po] -*.bak -*.BAK -*~ -*.orig -*.class -.cvsignore -Thumbs.db -*.py[co] -_darcs/* -CVS/* -.svn/* -RCS/* - -# kdevelop -.kdev -*.kdev4 - -# Lokalize -*lokalize* - -# eclipse -.project -.settings - -# netbeans -nbproject - -# geany -*.geany - -# Cloud9IDE -.settings.xml - -# vim ex mode -.vimrc - -# Mac OS -.DS_Store - -# WebFinger -.well-known -/.buildpath diff --git a/apps/journal/COPYING-AGPL b/apps/journal/COPYING-AGPL deleted file mode 100644 index dba13ed2dd..0000000000 --- a/apps/journal/COPYING-AGPL +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/apps/journal/COPYING-README b/apps/journal/COPYING-README deleted file mode 100644 index 18f06caa3e..0000000000 --- a/apps/journal/COPYING-README +++ /dev/null @@ -1,10 +0,0 @@ -Files in TAL Templating System for ownCloud are licensed under the Affero General Public License version 3, -the text of which can be found in COPYING-AGPL, or any later version of the AGPL, -unless otherwise noted. - -Licensing of components: -* PHPTAL - http://phptal.org/ : LGPL - -All unmodified files from these and other sources retain their original copyright -and license notices: see the relevant individual files. - diff --git a/apps/journal/Changelog b/apps/journal/Changelog deleted file mode 100644 index 08b20831be..0000000000 --- a/apps/journal/Changelog +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -### 0.1 - -- First release. \ No newline at end of file diff --git a/apps/journal/README.md b/apps/journal/README.md deleted file mode 100644 index 7c06e4f038..0000000000 --- a/apps/journal/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# Journal/Notes app for ownCloud - -## Features - -- Saves notes/journal entries as VJOURNAL records in the ownCloud Calendar. - -- Integrates with ownClouds search backend. - -- Sort entries by date/time ascending/descending or summary ascending/descending. - -- Plain text or rich text editing (rich text editing is still buggy and immature). - -- Syncs with KDEPIMs Journal part. - -- Completed tasks from the Task app can be automatically added as journal entries. - -- Stores entry data as json objects in each element for quich access and to minimize ajax calls. - -To install this app you will first have to install the [TAL Page Templates for ownCloud](/tanghus/tal#readme) app. - -## Installation from git - -1. Go to your ownCloud apps dir and clone the repo there: -
-	 cd owncloud/apps
-	 git clone git://github.com/tanghus/journal.git
- -2. From your browser go to the ownCloud apps page (`/settings/apps.php`) and enable the Journal app. - -3. After a page refresh you should see the Journal app in the main menu. - - -## DISCLAIMER - -There's no garantee this app won't eat your data, chew it up and spit it out. It works directly on the calendar app data -though not touching anything but VJOURNAL entries. [Always backup!](http://tanghus.net/2012/04/backup-owncloud-calendar-and-contacts/) - -Please report any issues at the [github issue tracker](https://github.com/tanghus/journal/issues) \ No newline at end of file diff --git a/apps/journal/TODO b/apps/journal/TODO deleted file mode 100644 index 2827136581..0000000000 --- a/apps/journal/TODO +++ /dev/null @@ -1,13 +0,0 @@ - -- Fix categories. - -- Hide empty elements? - -- Check if entered text in one mode gets transfered when changing modes. - -- Make edit area fit size and scrollable. - -- Add an "only read from this calendar" checkbox. - -- Test, test, test in other browser as well. - diff --git a/apps/journal/ajax/categories/categoriesfor.php b/apps/journal/ajax/categories/categoriesfor.php deleted file mode 100644 index 846af300de..0000000000 --- a/apps/journal/ajax/categories/categoriesfor.php +++ /dev/null @@ -1,28 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('contacts'); - -$id = isset($_GET['id'])?$_GET['id']:null; -if(is_null($id)) { - OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('No ID provided')))); - exit(); -} -$vcard = OC_Contacts_App::getContactVCard( $id ); -foreach($vcard->children as $property){ - //OCP\Util::writeLog('contacts','ajax/categories/checksumfor.php: '.$property->name, OCP\Util::DEBUG); - if($property->name == 'CATEGORIES') { - $checksum = md5($property->serialize()); - OCP\JSON::success(array('data' => array('value'=>$property->value, 'checksum'=>$checksum))); - exit(); - } -} -OCP\JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.')))); -?> diff --git a/apps/journal/ajax/categories/delete.php b/apps/journal/ajax/categories/delete.php deleted file mode 100644 index e68d608c5d..0000000000 --- a/apps/journal/ajax/categories/delete.php +++ /dev/null @@ -1,54 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('contacts'); -OCP\JSON::callCheck(); - -foreach ($_POST as $key=>$element) { - debug('_POST: '.$key.'=>'.print_r($element, true)); -} - -require_once('../util.php'); - -$categories = isset($_POST['categories'])?$_POST['categories']:null; - -if(is_null($categories)) { - bailOut(OC_Contacts_App::$l10n->t('No categories selected for deletion.')); -} - -debug(print_r($categories, true)); - -$addressbooks = OC_Contacts_Addressbook::all(OCP\USER::getUser()); -if(count($addressbooks) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No address books found.')); -} -$addressbookids = array(); -foreach($addressbooks as $addressbook) { - $addressbookids[] = $addressbook['id']; -} -$contacts = OC_Contacts_VCard::all($addressbookids); -if(count($contacts) == 0) { - bailOut(OC_Contacts_App::$l10n->t('No contacts found.')); -} - -$cards = array(); -foreach($contacts as $contact) { - $cards[] = array($contact['id'], $contact['carddata']); -} - -debug('Before delete: '.print_r($categories, true)); - -$catman = new OC_VCategories('contacts'); -$catman->delete($categories, $cards); -debug('After delete: '.print_r($catman->categories(), true)); -OC_Contacts_VCard::updateDataByID($cards); -OCP\JSON::success(array('data' => array('categories'=>$catman->categories()))); - -?> diff --git a/apps/journal/ajax/categories/list.php b/apps/journal/ajax/categories/list.php deleted file mode 100644 index ac8976fa0e..0000000000 --- a/apps/journal/ajax/categories/list.php +++ /dev/null @@ -1,17 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); - -$categories = OC_Journal_App::getCategories(); - -OCP\JSON::success(array('data' => array('categories'=>$categories))); - -?> diff --git a/apps/journal/ajax/categories/rescan.php b/apps/journal/ajax/categories/rescan.php deleted file mode 100644 index d746f9179f..0000000000 --- a/apps/journal/ajax/categories/rescan.php +++ /dev/null @@ -1,42 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); - -foreach ($_POST as $key=>$element) { - debug('_POST: '.$key.'=>'.print_r($element, true)); -} - -function bailOut($msg) { - OCP\JSON::error(array('data' => array('message' => $msg))); - OCP\Util::writeLog('journal','ajax/categories/rescan.php: '.$msg, OCP\Util::DEBUG); - exit(); -} -function debug($msg) { - OCP\Util::writeLog('journal','ajax/categories/rescan.php: '.$msg, OCP\Util::DEBUG); -} - -$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser()); -if(count($calendars) == 0) { - bailOut(OC_Calendar_App::$l10n->t('No calendars found.')); -} -$events = array(); -foreach($calendars as $calendar) { - $calendar_events = OC_Calendar_Object::all($calendar['id']); - $events = $events + $calendar_events; -} -if(count($events) == 0) { - bailOut(OC_Calendar_App::$l10n->t('No events found.')); -} - -OC_Calendar_App::scanCategories($events); -$categories = OC_Calendar_App::getCategoryOptions(); - -OCP\JSON::success(array('data' => array('categories'=>$categories))); \ No newline at end of file diff --git a/apps/journal/ajax/delete.php b/apps/journal/ajax/delete.php deleted file mode 100644 index 4013e4440a..0000000000 --- a/apps/journal/ajax/delete.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); -OCP\JSON::callCheck(); - -$id = isset($_POST['id'])?$_POST['id']:null; -if(is_null($id)) { - OCP\JSON::error(array('data'=>array('message' => OC_Journal_App::$l10n->t('ID is not set!')))); - exit; -} -$journal = OC_Calendar_App::getEventObject($id); -if($journal) { - OC_Calendar_Object::delete($id); - OCP\JSON::success(array('data' => array( 'id' => $id ))); -} else { - OCP\JSON::error(array('data' => array('id' => $id, 'message' => OC_Journal_App::$l10n->t('Could not find journal entry: '.$id)))); -} \ No newline at end of file diff --git a/apps/journal/ajax/entries.php b/apps/journal/ajax/entries.php deleted file mode 100644 index 03f2366d33..0000000000 --- a/apps/journal/ajax/entries.php +++ /dev/null @@ -1,36 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -// Init owncloud -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); - -$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); -$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); -session_write_close(); -$journals = array(); -foreach( $calendars as $calendar ){ - $calendar_journals = OC_Calendar_Object::all($calendar['id']); - foreach( $calendar_journals as $journal ) { - if($journal['objecttype']!='VJOURNAL') { - continue; - } - if(is_null($journal['summary'])) { - continue; - } - $object = OC_VObject::parse($journal['calendardata']); - $vjournalobj = $object->VJOURNAL; - try { - $journals[] = OC_Journal_App::arrayForJSON($journal['id'], $vjournalobj, $user_timezone); - } catch(Exception $e) { - OCP\Util::writeLog('journal', 'ajax/getentries.php. id: '.$journal['id'].' '.$e->getMessage(), OCP\Util::ERROR); - } - } -} - -OCP\JSON::success(array('data' => array('entries' => $journals))); diff --git a/apps/journal/ajax/saveproperty.php b/apps/journal/ajax/saveproperty.php deleted file mode 100644 index 016f922a9a..0000000000 --- a/apps/journal/ajax/saveproperty.php +++ /dev/null @@ -1,138 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -$htmlwrap = '%s'; -$divwrap = '
%s
'; -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); -OCP\JSON::callCheck(); - -$id = isset($_POST['id'])?$_POST['id']:null; -$property = isset($_POST['type'])?$_POST['type']:null; -$value = isset($_POST['value'])?$_POST['value']:null; -if(is_null($id)) { - OCP\JSON::error(array('data'=>array('message' => OC_Journal_App::$l10n->t('ID is not set!')))); - exit; -} -if(is_null($property)) { - OCP\JSON::error(array('data'=>array('message' => OC_Journal_App::$l10n->t('Property name is not set!')))); - exit; -} -if(is_null($value)) { - OCP\JSON::error(array('data'=>array('message' => OC_Journal_App::$l10n->t('Property value is not set!')))); - exit; -} - -foreach($_POST as $key => $val) { - error_log($key.': '.print_r($val, true)); -} - -$parameters = isset($_POST['parameters'])? $_POST['parameters']:null; -if($id == 'new') { - $vcalendar = OC_Journal_App::createVCalendar(); -} else { - $vcalendar = OC_Calendar_App::getVCalendar( $id ); -} -error_log('saveproperty: '.$property.': '.print_r($value, true)); -$vjournal = $vcalendar->VJOURNAL; -switch($property) { - case 'DESCRIPTION': - $hasgenericformat = false; - $haskdeformat = false; - if(!$vjournal->DESCRIPTION) { - $vjournal->setString('DESCRIPTION', $value); - } - if($parameters && isset($parameters['FORMAT']) && strtoupper($parameters['FORMAT']) == 'HTML') { - if($value[0] != '<') { // Fugly hack coming up - $value = sprintf($divwrap, $value); - } - $vjournal->DESCRIPTION->value = sprintf($htmlwrap, $value); - foreach($vjournal->DESCRIPTION->parameters as $parameter){ - if(stripos($parameter->name, 'X-KDE-TEXTFORMAT') !== false && stripos($parameter->value, 'HTML') !== false){ - $haskdeformat = true; - } - if(stripos($parameter->name, 'X-TEXTFORMAT') !== false && stripos($parameter->value, 'HTML') !== false){ - $hasgenericformat = true; - } - } - if(!$haskdeformat) { - try { - $vjournal->DESCRIPTION->add(new Sabre_VObject_Parameter('X-KDE-TEXTFORMAT', 'HTML')); - } catch (Exception $e) { - OCP\JSON::error(array('data'=>array('message'=>OC_Journal_App::$l10n->t('Error setting rich text format parameter: '.$e->getMessage())))); - exit(); - } - } - if(!$hasgenericformat) { // Add a more generic text formatting parameter in case other clients would use VJOURNAL this way. - try { - $vjournal->DESCRIPTION->add(new Sabre_VObject_Parameter('X-TEXTFORMAT', 'HTML')); - } catch (Exception $e) { - OCP\JSON::error(array('data'=>array('message'=>OC_Journal_App::$l10n->t('Error setting rich text format parameter: '.$e->getMessage())))); - exit(); - } - } - } else { - $vjournal->DESCRIPTION->value = $value; - } - break; - case 'DTSTART': - try { - $date_only = isset($_POST['date_only']) && (bool)$_POST['date_only'] == true?true:false; - $timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); - $timezone = new DateTimeZone($timezone); - //$dtstart = new DateTime($value, $timezone); - $dtstart = new DateTime('@'.$value); - $dtstart->setTimezone($timezone); - $type = Sabre_VObject_Property_DateTime::LOCALTZ; - if ($date_only) { - $type = Sabre_VObject_Property_DateTime::DATE; - } - $vjournal->setDateTime('DTSTART', $value, $type); - } catch (Exception $e) { - OCP\JSON::error(array('data'=>array('message'=>OC_Journal_App::$l10n->t('Invalid date/time: '.$e->getMessage())))); - exit(); - } - break; - case 'ORGANIZER': - case 'SUMMARY': - case 'CATEGORIES': - $vobject = $vjournal->getVObject(); - if(isset($vobject[$property])) { - $vobject[$property]['value'] = $value; - } else { - $vjournal->setString($property, $value); - } - break; - $vjournal->setString($property, $value); - break; - default: - OCP\JSON::error(array('data'=>array('message'=>'Unknown type: '.$property))); - exit(); -} - -$vjournal->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Property_DateTime::UTC); -$vjournal->setDateTime('DTSTAMP', 'now', Sabre_VObject_Property_DateTime::UTC); - -if($id == 'new') { - // TODO: Have a calendar ID parameter in request. - $cid = OCP\Config::getUserValue(OCP\User::getUser(), 'journal', 'default_calendar', null); - // Check that the calendar exists and that it's ours. - $cid = OC_Calendar_App::getCalendar($cid, true); - if(!$cid) { - OCP\Util::writeLog('journal', 'The default calendar '.$cid.' is either not owned by '.OCP\User::getUser().' or doesn\'t exist.', OCP\Util::WARN); - $calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); - $first_calendar = reset($calendars); - $cid = $first_calendar['id']; - } - $id = OC_Calendar_Object::add($cid, $vcalendar->serialize()); -} else { - OC_Calendar_Object::edit($id, $vcalendar->serialize()); -} -$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); -$journal_info = OC_Journal_App::arrayForJSON($id, $vjournal, $user_timezone); -OCP\JSON::success(array('data' => $journal_info)); diff --git a/apps/journal/ajax/setdefaultcalendar.php b/apps/journal/ajax/setdefaultcalendar.php deleted file mode 100644 index a82c1e3cf1..0000000000 --- a/apps/journal/ajax/setdefaultcalendar.php +++ /dev/null @@ -1,36 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('journal'); -OCP\JSON::callCheck(); - -$id = isset($_POST['id'])?$_POST['id']:null; -if(is_null($id)) { - OCP\JSON::error(array('data'=>array('message' => OC_Journal_App::$l10n->t('ID is not set!')))); - exit; -} -if(OCP\Config::setUserValue(OCP\USER::getUser(), 'journal', 'default_calendar', $id)) { - OC_Calendar_Object::delete($id); - OCP\JSON::success(array('data' => array( 'id' => $id ))); -} else { - OCP\JSON::error(array('data' => array('id' => $id, 'message' => OC_Journal_App::$l10n->t('Could not set default calendar: '.$id)))); -} \ No newline at end of file diff --git a/apps/journal/ajax/util.php b/apps/journal/ajax/util.php deleted file mode 100644 index b690b2e194..0000000000 --- a/apps/journal/ajax/util.php +++ /dev/null @@ -1,40 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -function bailOut($msg, $tracelevel=1, $debuglevel=OCP\Util::ERROR) { - OCP\JSON::error(array('data' => array('message' => $msg))); - debug($msg, $tracelevel, $debuglevel); - exit(); -} - -function debug($msg, $tracelevel=0, $debuglevel=OCP\Util::DEBUG) { - if(PHP_VERSION >= "5.4") { - $call = debug_backtrace(false, $tracelevel+1); - } else { - $call = debug_backtrace(false); - } - error_log('trace: '.print_r($call, true)); - $call = $call[$tracelevel]; - if($debuglevel !== false) { - OCP\Util::writeLog('journal', $call['file'].'. Line: '.$call['line'].': '.$msg, $debuglevel); - } -} diff --git a/apps/journal/appinfo/app.php b/apps/journal/appinfo/app.php deleted file mode 100644 index 5f33d40399..0000000000 --- a/apps/journal/appinfo/app.php +++ /dev/null @@ -1,18 +0,0 @@ - 'journal_index', - 'order' => 11, - 'href' => OCP\Util::linkTo( 'journal', 'index.php' ), - 'icon' => OCP\Util::imagePath( 'journal', 'journal.png' ), - 'name' => $l->t('Journal'))); - -OC_Search::registerProvider('OC_Search_Provider_Journal'); -OCP\App::registerPersonal('journal','settings'); \ No newline at end of file diff --git a/apps/journal/appinfo/info.xml b/apps/journal/appinfo/info.xml deleted file mode 100644 index 426e38eb9f..0000000000 --- a/apps/journal/appinfo/info.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - journal - Journal - 0.1 - AGPL - Thomas Tanghus - 5 - true - Journal view from calendar - diff --git a/apps/journal/css/journal.css b/apps/journal/css/journal.css deleted file mode 100644 index ac2ae74c65..0000000000 --- a/apps/journal/css/journal.css +++ /dev/null @@ -1,19 +0,0 @@ -#leftcontent a { font-weight: bold; } -#metadata { position: fixed; background-color: #ccc; width: 20em; right: 0; top: 6.5em; bottom: 0; overflow: auto; padding: 1em; margin: 0; font-size: 1em; font-weight: bold; } -#metadata :disabled.property { background-color: #ccc; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } -#entry { position: fixed; background: #fff; top: 6.5em; bottom: 0; left: 32.5em !important; right: 22em; padding: 1em; margin: 0; } -div.propertycontainer[data-type="DESCRIPTION"] { height: 90%; } -#description { width: 95%; height: 90%; } -.rte-content { position: absolute; left: 1em; right: 1em; top: 7em; bottom: 1em; overflow: auto; } -#summary { width: 95%; font-size: 1.4em; font-weight: bold; height: 1.6em; } -.editable,.content { font-size: 1.2em; background-color: #fff !important; border: 1px solid #fff !important; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; cursor: text; } -.editable:hover,.editable:focus,.editable:hover:active { border: 1px solid #1d2d44 !important; } -#categories,#organizer,#location,#link { width: 18em; clear: right; } -#dtstartdate { width: 10em; } -#dtstarttime { width: 5em; } -.loading { background: url('%webroot%/core/img/loading.gif') no-repeat center !important; cursor: wait; } -.action { padding-left: 0.5em; } -label,dt { color: #aaa; } -label:hover, dt:hover { color: #333; } -.required { color: red; border: 3px solid red; } -input { font-size: 1em; font-weight: bold; } \ No newline at end of file diff --git a/apps/journal/css/rte.css b/apps/journal/css/rte.css deleted file mode 100644 index e786599002..0000000000 --- a/apps/journal/css/rte.css +++ /dev/null @@ -1,7 +0,0 @@ -.rte-toolbar { margin: 0; width:100%; height:22px; padding:0; list-style-type:none; } -.rte-toolbar li button, .rte-toolbar li a { float:left; cursor:pointer; opacity: 0.6; padding:0; margin: 0; border: 0; border-radius: 0; outline: 0; background: inherit; } -.rte-toolbar li button:hover { opacity: 0.8; } -.rte-content { cursor:text;position:absolute; border-color:#000;border-style:solid;white-space: pre-wrap;word-wrap:break-word; padding: 0.2em; } -.rte-content ul { list-style: circle inside; } -.rte-content li { padding-left: 1em; } - diff --git a/apps/journal/img/bold.svg b/apps/journal/img/bold.svg deleted file mode 100644 index 2b06228258..0000000000 --- a/apps/journal/img/bold.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/journal/img/indent-less.svg b/apps/journal/img/indent-less.svg deleted file mode 100644 index 246089c293..0000000000 --- a/apps/journal/img/indent-less.svg +++ /dev/null @@ -1,300 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Unindent - - - - Jakub Steiner - - - - - indent - less - unindent - - - - - - Andreas Nilsson - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/indent-more.svg b/apps/journal/img/indent-more.svg deleted file mode 100644 index 4e137cf452..0000000000 --- a/apps/journal/img/indent-more.svg +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Indent More - - - - Jakub Steiner - - - - - indent - more - - - - http://jimmac.musichall.cz - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/italic.svg b/apps/journal/img/italic.svg deleted file mode 100644 index 1eeb4fc132..0000000000 --- a/apps/journal/img/italic.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/apps/journal/img/journal.png b/apps/journal/img/journal.png deleted file mode 100644 index f95dd8e9f3aab75e8d5ce35984c0dad972eda924..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 581 zcmV-L0=oT)P)k3U}DPmgQ{0LO9Qx-MF+*0<$y`QzQL`t>fLTCM(bbEDBfI2=Ygorb1qAcSNC z1d=3yF$Pf-0RX=5<9Ixx+wH=#EX3n+FvhT0EUf*0|M|ZJ>-8FjVZgR+0Kjgy1Em!G ze!sL@tzH5Ij4{Zv3`!{?kqFxDHn!XCZ6=jULDzMEI2`^2{%GMf!Dh38VHg3kX_}bL zX1?pX9|8fdTX0<$s;a`Wted&h=|Glc2!eo0rSkG7!R2zn;c!5yR6?`a#C$%7X`0An zGDs$q5Cj3mVi9i=oK7cbng#%<)oKt$5xHCru~-a*5D-HAt0zFRpPbQN`&zVw6JplLx=8&(j TN?Z-m00000NkvXXu0mjfK_B*2 diff --git a/apps/journal/img/journal.svg b/apps/journal/img/journal.svg deleted file mode 100644 index 2ee85ef069..0000000000 --- a/apps/journal/img/journal.svg +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/justify-center.svg b/apps/journal/img/justify-center.svg deleted file mode 100644 index 7a3a7ffb97..0000000000 --- a/apps/journal/img/justify-center.svg +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Justify Center - 2005-10-29 - - - Andreas Nilsson - - - - - justify - center - format - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/justify-fill.svg b/apps/journal/img/justify-fill.svg deleted file mode 100644 index f9a530bdae..0000000000 --- a/apps/journal/img/justify-fill.svg +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Justify Center - 2005-10-29 - - - Andreas Nilsson - - - - - justify - center - format - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/justify-left.svg b/apps/journal/img/justify-left.svg deleted file mode 100644 index ed5bab4651..0000000000 --- a/apps/journal/img/justify-left.svg +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Justify Left - 2005-10-29 - - - Andreas Nilsson - - - - - justify - left - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/justify-right.svg b/apps/journal/img/justify-right.svg deleted file mode 100644 index affb129539..0000000000 --- a/apps/journal/img/justify-right.svg +++ /dev/null @@ -1,269 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - Justify Right - 2005-10-29 - - - Andreas Nilsson - - - - - justify - left - format - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/journal/img/list.svg b/apps/journal/img/list.svg deleted file mode 100644 index b253c0ab50..0000000000 --- a/apps/journal/img/list.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/apps/journal/img/strikethrough.svg b/apps/journal/img/strikethrough.svg deleted file mode 100644 index 528907cebe..0000000000 --- a/apps/journal/img/strikethrough.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/journal/img/underline.svg b/apps/journal/img/underline.svg deleted file mode 100644 index 534bed6ea2..0000000000 --- a/apps/journal/img/underline.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/journal/index.php b/apps/journal/index.php deleted file mode 100644 index bfe882376e..0000000000 --- a/apps/journal/index.php +++ /dev/null @@ -1,72 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ -$errors = array(); -$l = new OC_L10N('journal'); -OCP\User::checkLoggedIn(); - -$required_apps = array( - array('id' => 'tal', 'name' => 'TAL Page Templates'), - array('id' => 'journal', 'name' => 'Journal'), - array('id' => 'contacts', 'name' => 'Contacts'), -); -foreach($required_apps as $app) { - if(!OCP\App::isEnabled($app['id'])) { - $error = (string)$l->t('The %%s app isn\'t enabled! Please enable it here: Enable %%s app'); - $errors[] = sprintf($error, $app['name'],OCP\Util::linkTo('settings', 'apps'), $app['id'], $app['name']); - } -} - -if(count($errors) == 0) { - $calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); - if( count($calendars) == 0 ) { - $error = (string)$l->t('You have no calendars. Please add one at the Calendar app'); - $errors[] = sprintf($error, OCP\Util::linkTo('calendar', 'index.php')); - } - // Load a specific entry? - $id = isset( $_GET['id'] ) ? $_GET['id'] : null; - - OCP\Util::addScript('3rdparty/timepicker', 'jquery.ui.timepicker'); - OCP\Util::addScript('contacts','jquery.multi-autocomplete'); - OCP\Util::addScript('','oc-vcategories'); - OCP\Util::addScript('journal', 'jquery.rte'); - OCP\Util::addScript('journal', 'jquery.textchange'); - OCP\Util::addScript('journal', 'journal'); - OCP\Util::addscript('tal','modernizr'); - OCP\Util::addStyle('3rdparty/timepicker', 'jquery.ui.timepicker'); - OCP\Util::addStyle('journal', 'rte'); - OCP\Util::addStyle('journal', 'journal'); - OCP\App::setActiveNavigationEntry('journal_index'); - - $categories = OC_Calendar_App::getCategoryOptions(); -} - -//$tmpl = new OCP\Template('journal', 'journals', 'user'); -if($errors) { - $tmpl = new OCP\Template( "journal", "rtfm", "user" ); - $tmpl->assign('errors',$errors, false); -} else { - $tmpl = new OC_TALTemplate('journal', 'index', 'user'); - $tmpl->assign('categories', $categories); - $tmpl->assign('calendars', $calendars); - $tmpl->assign('id',$id); -} -$tmpl->printPage(); diff --git a/apps/journal/js/expanding.js b/apps/journal/js/expanding.js deleted file mode 100644 index 17139f27ff..0000000000 --- a/apps/journal/js/expanding.js +++ /dev/null @@ -1,118 +0,0 @@ -// Expanding Textareas -// https://github.com/bgrins/ExpandingTextareas - -(function(factory) { - // Add jQuery via AMD registration or browser globals - if (typeof define === 'function' && define.amd) { - define([ 'jquery' ], factory); - } - else { - factory(jQuery); - } -}(function ($) { - $.expandingTextarea = $.extend({ - autoInitialize: true, - initialSelector: "textarea.expanding", - opts: { - resize: function() { } - } - }, $.expandingTextarea || {}); - - var cloneCSSProperties = [ - 'lineHeight', 'textDecoration', 'letterSpacing', - 'fontSize', 'fontFamily', 'fontStyle', - 'fontWeight', 'textTransform', 'textAlign', - 'direction', 'wordSpacing', 'fontSizeAdjust', - 'wordWrap', - 'borderLeftWidth', 'borderRightWidth', - 'borderTopWidth','borderBottomWidth', - 'paddingLeft', 'paddingRight', - 'paddingTop','paddingBottom', - 'marginLeft', 'marginRight', - 'marginTop','marginBottom', - 'boxSizing', 'webkitBoxSizing', 'mozBoxSizing', 'msBoxSizing' - ]; - - var textareaCSS = { - position: "absolute", - height: "100%", - resize: "none" - }; - - var preCSS = { - visibility: "hidden", - border: "0 solid", - whiteSpace: "pre-wrap" - }; - - var containerCSS = { - position: "relative" - }; - - function resize() { - $(this).closest('.expandingText').find("div").text(this.value + ' '); - $(this).trigger("resize.expanding"); - } - - $.fn.expandingTextarea = function(o) { - - var opts = $.extend({ }, $.expandingTextarea.opts, o); - - if (o === "resize") { - return this.trigger("input.expanding"); - } - - if (o === "destroy") { - this.filter(".expanding-init").each(function() { - var textarea = $(this).removeClass('expanding-init'); - var container = textarea.closest('.expandingText'); - - container.before(textarea).remove(); - textarea - .attr('style', textarea.data('expanding-styles') || '') - .removeData('expanding-styles'); - }); - - return this; - } - - this.filter("textarea").not(".expanding-init").addClass("expanding-init").each(function() { - var textarea = $(this); - - textarea.wrap("
"); - textarea.after("
"); - - var container = textarea.parent().css(containerCSS); - var pre = container.find("pre").css(preCSS); - - // Store the original styles in case of destroying. - textarea.data('expanding-styles', textarea.attr('style')); - textarea.css(textareaCSS); - - $.each(cloneCSSProperties, function(i, p) { - var val = textarea.css(p); - - // Only set if different to prevent overriding percentage css values. - if (pre.css(p) !== val) { - pre.css(p, val); - } - }); - - textarea.bind("input.expanding propertychange.expanding", resize); - resize.apply(this); - - if (opts.resize) { - textarea.bind("resize.expanding", opts.resize); - } - }); - - return this; - }; - - $(function () { - if ($.expandingTextarea.autoInitialize) { - $($.expandingTextarea.initialSelector).expandingTextarea(); - } - }); - -})); diff --git a/apps/journal/js/journal.js b/apps/journal/js/journal.js deleted file mode 100644 index 2611b09c55..0000000000 --- a/apps/journal/js/journal.js +++ /dev/null @@ -1,432 +0,0 @@ -String.prototype.unEscape = function(){ - str = this; - return str.replace(/\\"/g, '"'); -}; -String.prototype.stripTags = function(){ - tags = this; - stripped = tags.replace(/<(.|\n)*?>/g, ''); - return stripped; -}; -String.prototype.zeroPad = function(digits) { - n = this.toString(); - while (n.length < digits) { - n = '0' + n; - } - return n; -} - -OC.Journal = { - init:function() { - this.setEnabled(false); - // Fetch journal entries. If it's a direct link 'id' will be loaded. - OC.Journal.Journals.update(id); - }, - categoriesChanged:function(newcategories) { // Categories added/deleted. - categories = $.map(newcategories, function(v) {return v;}); - $('#categories').multiple_autocomplete('option', 'source', categories); - var categorylist = $('#categories_value').find('input'); - $.getJSON(OC.filePath('journal', 'ajax', 'categories/categoriesfor.php'),{'id':Contacts.UI.Card.id},function(jsondata){ - if(jsondata.status == 'success'){ - $('#categories_value').data('checksum', jsondata.data.checksum); - categorylist.val(jsondata.data.value); - } else { - OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - } - }); - }, - propertyContainerFor:function(obj) { - if($(obj).hasClass('propertycontainer')) { - return $(obj); - } - return $(obj).parents('.propertycontainer').first(); - }, - required:function(event){ // eventhandler for required elements - // FIXME: This doesn't seem to work. - console.log('blur on required'); - var obj = $(event.target); - $(obj).addClass('required'); - if($(this).val().trim() == '') { - $('This field is required!').appendTo($(obj)); - return; - } else { - $(obj).removeClass('required'); - $(obj).off('blur', OC.Journal.required); - } - }, - setEnabled:function(state) { - if(state == undefined) { state = true; } - console.log('OC.Journal.setEnabled: ' + state); - if(state) { - $('#description').rte('setEnabled', true); - if($('#description').rte('mode') == 'html') { - $('#editortoolbar li').show(); - } - $('#togglemode').show(); - $('#summary').addClass('editable'); - $('.property,#also_time').each(function () { - $(this).attr('disabled', false); - }); - } else { - $('#description').rte('setEnabled', false); - $('#editortoolbar .richtext, #togglemode').hide(); - $('#summary').removeClass('editable'); - $('.property,#also_time').each(function () { - $(this).attr('disabled', true); - }); - } - }, - toggleMode:function() { - console.log('togglemode'); - $('#description').rte('toggleMode'); - $('#editortoolbar li.richtext').toggle(); - }, - Entry:{ - id:'', - data:undefined, - add:function() { - // TODO: wrap a DIV around the summary field with a suggestion(?) to fill out this field first. See OC.Journal.required - // Remember to reenable all controls. - $('#leftcontent lidata-id="'+this.id+'"').removeClass('active'); - this.id = 'new'; - this.data = undefined; - $('.property').each(function () { - switch($(this).get(0).nodeName) { - case 'DIV': - $(this).html(''); - break; - case 'INPUT': - case 'TEXTAREA': - $(this).val(''); - break; - default: - console.log('OC.Journal.Entry.add. Forgot: ' + $(this).get(0).nodeName); - break; - } - }); - $('#description').rte('setEnabled', false); - $('#editortoolbar li.richtext').hide(); - $('#editable').attr('checked', true); - OC.Journal.setEnabled(true); - }, - createEntry:function(data) { - var date = new Date(parseInt(data.dtstart)*1000); - var timestring = (data.only_date?'':' ' + date.toLocaleTimeString()); - return $('
  • '+data.summary.unEscape()+'
    '+date.toDateString()+timestring+'
  • ').data('entry', data); - }, - loadEntry:function(id, data) { - //$(document).off('change', '.property'); - console.log('loadEntry: ' + id + ': ' + data.summary); - this.id = id; - this.data = data; - $('#entry').data('id', id); - console.log('summary: ' + data.summary.unEscape()); - $('#summary').val(data.summary.unEscape()); - $('#organizer').val(data.organizer.value.split(':')[1]); - var format = data.description.format; - console.log('format: '+format); - $('#description').rte(format, data.description.value.unEscape()); - $('#description').rte('mode', format); - //$('#description').expandingTextarea('resize'); - (format=='html'&&$('#editable').get(0).checked?$('#editortoolbar li.richtext').show():$('#editortoolbar li.richtext').hide()); - $('#location').val(data.location); - $('#categories').val(data.categories.join(',')); - $('#categories').multiple_autocomplete('option', 'source', categories); - console.log('Trying to parse: '+data.dtstart); - var date = new Date(parseInt(data.dtstart)*1000); - //$('#dtstartdate').val(date.getDate()+'-'+date.getMonth()+'-'+date.getFullYear()); // - $('#dtstartdate').datepicker('setDate', date); - if(data.only_date) { - $('#dtstarttime').hide(); - $('#also_time').attr('checked', false); - //$('#also_time').get(0).checked = false; - } else { - // timepicker('setTime', ...) triggers a 'change' event, so you have to jump through hoops here ;-) - $('#dtstarttime').val(date.getHours().toString().zeroPad(2)+':'+date.getMinutes().toString().zeroPad(2)); - $('#dtstarttime').show(); - $('#also_time').attr('checked', true); - //$('#also_time').get(0).checked = true; - } - console.log('dtstart: '+date); - }, - saveproperty:function(obj) { - if(!this.id) { // we are adding an entry and want a response back from the server. - this.id = 'new'; - console.log('OC.Journal.Entry.saveproperty: We need to add a new one.'); - //return; - } - var container = OC.Journal.propertyContainerFor(obj); - var params = {'id':this.id}; - params['type'] = container.data('type'); - params['parameters'] = {}; - switch(params['type']) { - case 'ORGANIZER': - case 'LOCATION': - case 'CATEGORIES': - params['value'] = $(obj).val(); - break; - case 'SUMMARY': - if(this.id == 'new' && $(obj).val().trim() == '') { - $(obj).focus(); - $(obj).addClass('required'); - $(obj).on('blur', OC.Journal.required); - return; - } - params['value'] = $(obj).val(); - break; - case 'DESCRIPTION': - // Check if we get the description from the textarea or the contenteditable. - var format = ($(obj).get(0).nodeName == 'DIV' ? 'html' : 'text'); // FIXME: should check rte instead. - var value = $('#description').rte(format); // calls either the 'text' or 'html' method of the rte. - //var value = ($(obj).get(0).nodeName == 'DIV' ? $(obj).html() : $(obj).text()); - console.log('nodeName: ' + $(obj).get(0).nodeName); - params['value'] = value; - params['parameters']['FORMAT'] = format.toUpperCase(); - break; - case 'DTSTART': - var date = $('#dtstartdate').val(); - var time = $('#dtstarttime').val(); - var datetime = new Date(parseInt(date.substring(6, 10)), parseInt(date.substring(3, 5)), parseInt(date.substring(0, 2)) , parseInt(time.substring(0, 2)), parseInt(time.substring(3, 5)), 0, 0); - params['value'] = datetime.getTime()/1000; - break; - default: - $.extend(1, $(obj).serializeArray(), params); - break; - } - self = this; - $.post(OC.filePath('journal', 'ajax', 'saveproperty.php'), params, function(jsondata) { - if(jsondata.status == 'success') { - if(self.id == 'new') { - self.loadEntry(jsondata.data.id, jsondata.data); - } else { - $('#leftcontent li[data-id="'+self.id+'"]').remove(); - } - var item = self.createEntry(jsondata.data); - $('#leftcontent').append(item); - OC.Journal.Journals.doSort(); - OC.Journal.Journals.scrollTo(self.id); - // add error checking - console.log('successful save'); - } else { - OC.dialogs.alert(jsondata.data.message.text, t('contacts', 'Error')); - } - }); - }, - doExport:function() { - document.location.href = OC.linkTo('calendar', 'export.php') + '?eventid=' + this.id; - }, - doDelete:function() { - // TODO: Do something when there are no more entries. - if(this.id == 'new') { return; } - $('#delete').tipsy('hide'); - self = this; - OC.dialogs.confirm(t('contacts', 'Are you sure you want to delete this entry?'), t('journal', 'Warning'), function(answer) { - if(answer == true) { - $.post(OC.filePath('journal', 'ajax', 'delete.php'), {'id': self.id}, function(jsondata) { - if(jsondata.status == 'success') { - var curlistitem = $('#leftcontent li[data-id="'+self.id+'"]'); - var newlistitem = curlistitem.prev('li'); - if(!$(newlistitem).is('li')) { - newlistitem = curlistitem.next('li'); - } - if(!$(newlistitem).is('li')) { - alert('No more entries. Do something!!!'); - } - $(newlistitem).addClass('active'); - console.log('newlistitem: ' + newlistitem.toString()); - curlistitem.remove(); - var data = newlistitem.data('entry'); - self.loadEntry(data.id, data); - console.log('successful delete'); - } else { - OC.dialogs.alert(jsondata.data.message.text, t('contacts', 'Error')); - } - }); - } - }); - }, - }, - Journals:{ - sortmethod:undefined, - doSort:function(method) { - if(method) { - this.sortmethod = method; - } else { - method = this.sortmethod; - } - // Thanks to http://www.java2s.com/Tutorial/JavaScript/0220__Array/Usinganalphabeticalsortmethodonstrings.html - // and http://stackoverflow.com/questions/4258974/sort-list-based-on-data-attribute-using-jquery-metadata-plugin#4259074 - // and http://stackoverflow.com/questions/8882418/jquery-sorting-lib-that-supports-multilanguage-sorting - compareDateTimeAsc = function(a, b){ - return (parseInt(a.dtstart) > parseInt(b.dtstart)?-1:1); - } - compareDateTimeDesc = function(a, b){ - return (parseInt(b.dtstart) < parseInt(a.dtstart)?-1:1); - } - compareSummaryAsc = function(a, b){ - return b.summary.toLowerCase().localeCompare(a.summary.toLowerCase()); - } - compareSummaryDesc = function(a, b){ - return a.summary.toLowerCase().localeCompare(b.summary.toLowerCase()); - } - var func; - switch(method) { - case 'dtasc': - func = compareDateTimeAsc; - break; - case 'dtdesc': - func = compareDateTimeDesc; - break; - case 'sumasc': - func = compareSummaryAsc; - break; - case 'sumdesc': - func = compareSummaryDesc; - break; - default: - var func = compareDateTimeDesc; - break; - } - - var arr = [] - // loop through each list item and get the metadata - $('#leftcontent li').each(function () { - var meta = $(this).data('entry'); - meta.elem = $(this); - arr.push(meta); - }); - arr.sort(func); - - //Foreach item append it to the container. The first i arr will then end up in the top - $.each(arr, function(index, item){ - item.elem.appendTo(item.elem.parent()); - }); - }, - update:function(id) { - console.log('update: ' + id); - self = this; - $('#leftcontent').addClass('loading'); - $.getJSON(OC.filePath('journal', 'ajax', 'entries.php'), function(jsondata) { - if(jsondata.status == 'success') { - var entries = $('#leftcontent').empty(); - $(jsondata.data.entries).each(function(i, entry) { - entries.append(OC.Journal.Entry.createEntry(entry)); - }); - $('#leftcontent').removeClass('loading'); - self.doSort('dtasc'); - console.log('Count: ' + $('#leftcontent li').length); - if($('#leftcontent li').length > 0 ){ - var firstitem; - if(id) { - firstitem = $('#leftcontent li[data-id="'+id+'"]'); - } else { - firstitem = $('#leftcontent li').first(); - id = firstitem.data('entry').id; - } - firstitem.addClass('active'); - self.scrollTo(id); - OC.Journal.Entry.loadEntry(firstitem.data('id'), firstitem.data('entry')); - } - } else { - OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error')); - } - }); - }, - scrollTo:function(id){ - var item = $('#leftcontent li[data-id="'+id+'"]'); - if(item) { - try { - $('#leftcontent').animate({scrollTop: $('#leftcontent li[data-id="'+id+'"]').offset().top-70}, 'slow','swing'); - } catch(e) {} - } - } - } -}; - -$(document).ready(function(){ - OCCategories.changed = OC.Journal.categoriesChanged; - OCCategories.app = 'calendar'; - - // Initialize controls. - $('#categories').multiple_autocomplete({source: categories}); - //$('#categories').multiple_autocomplete('option', 'source', categories); - $('#dtstartdate').datepicker({dateFormat: 'dd-mm-yy'}); - $('#dtstarttime').timepicker({timeFormat: 'hh:mm', showPeriodLabels:false}); - $('#description').rte({classes: ['property','content']}); - $('.tip').tipsy(); - - OC.Journal.init(); - - // Show the input with a direcy link the journal entry, binds an event to close - // it on blur and removes the binding again afterwards. - $('#showlink').on('click', function(event){ - console.log('showlink'); - $('#link').toggle('slow').val(totalurl+'&id='+OC.Journal.Entry.id).focus(). - on('blur',function(event) {$(this).hide()}).off('blur', $(this)); - return false; - }); - - $('#rightcontent').on('change', '.property', function(event){ - OC.Journal.Entry.saveproperty(this); - }); - - $('#controls').on('click', '#add', function(event){ - OC.Journal.Entry.add(); - }); - - $('#metadata').on('change', '#also_time', function(event){ - $('#dtstarttime').toggle().trigger('change'); - }); - - $('#metadata').on('click', '#export', function(event){ - OC.Journal.Entry.doExport(); - }); - - $('#metadata').on('click', '#editcategories', function(event){ - OCCategories.edit(); - }); - - $('#metadata').on('click', '#delete', function(event){ - OC.Journal.Entry.doDelete(); - }); - - $('#controls').on('change', '#entrysort', function(event){ - OC.Journal.Journals.doSort($(this).val()); - }); - - // Proxy click. - $('#leftcontent').on('keydown', '#leftcontent', function(event){ - if(event.which == 13) { - $('#leftcontent').click(event); - } - }); - // Journal entry clicked - $(document).on('click', '#leftcontent', function(event){ - var $tgt = $(event.target); - var item = $tgt.is('li')?$($tgt):($tgt).parents('li').first(); - var id = item.data('id'); - item.addClass('active'); - var oldid = $('#entry').data('id'); - console.log('oldid: ' + oldid); - if(oldid != 0){ - $('#leftcontent li[data-id="'+oldid+'"]').removeClass('active'); - } - OC.Journal.Entry.loadEntry(id, item.data('entry')); - return false; - }); - // Editor command. - $('.rte-toolbar button').on('click', function(event){ - console.log('cmd: ' + $(this).data('cmd')); - $('#description').rte('formatText', $(this).data('cmd')); - event.preventDefault(); - return false; - }); - // Toggle text/html editing mode. - $('#togglemode').on('click', function(event){ - OC.Journal.toggleMode(true); - return false; - }); - $('#editable').on('change', function(event){ - OC.Journal.setEnabled($(this).get(0).checked); - }); - -}); diff --git a/apps/journal/js/jquery.rte.js b/apps/journal/js/jquery.rte.js deleted file mode 100644 index ca7b61d719..0000000000 --- a/apps/journal/js/jquery.rte.js +++ /dev/null @@ -1,244 +0,0 @@ -// http://wiki.jqueryui.com/w/page/12138135/Widget%20factory - -(function( $ ) { - -$.widget( 'ui.rte', { - // These options will be used as defaults - options: { - disabled: true, - mode: 'html' - }, - // Set up the widget - _create: function() { - console.log('_create'); - var self = this, - dirty = false, - textarea = this.element; //.hide(), - pos = textarea.position(); - //this.element.text = this.text; - this.mirror = $('
    ').insertAfter(textarea).show(); - textarea.hide(); - this.formatText('styleWithCSS', true); - this.validtags = ['A','P','STRONG', 'B', 'I', 'SPAN', 'DIV', 'OL', 'UL', 'LI', 'DL', 'DT', 'DD']; - this.enabled = true; - - /*$(window).resize(function() { - console.log('resize: '); - });*/ - - this.mirror.keydown(function(event){ - if(event.which == 13) { - self.insertAtCaret('
    '); - } - }); - this.mirror.keyup(function() { - console.log('keyup, set dirty.'); - self.dirty = true; - }); - this.mirror.blur(function() { - console.log('blur: '); - if(self.dirty) { - self.mirror.trigger('change'); - self.dirty = false; - } - }); - - }, - _init: function() { - console.log('_init'); - self = this; - $.each(this.options, function(key, value) { - self._setOption(key, value); - }); - }, - text: function(str) { - console.log('function text'); - if(str != undefined) { - this.mirror.html(str); - this.element.text(str); - } else { - console.log('returning: ' + this.element.val()); - return this.element.val(); - } - }, - html: function(str) { - console.log('function html'); - if(str != undefined) { - console.log('str: ' + str); - var $str; - try { - $str = $(str); - this.mirror.empty().html($str); // Call empty() for IE 8. - this.element.text($str.text()); - } catch(e) { - console.log(e.message); - this.mirror.empty().html(str); - this.element.text(str); - } - //console.log('length: ' + $str.length); - //this.mirror.get(0).contenteditable=false; - } else { - console.log('returning: ' + this.mirror.html()); - return this.mirror.html(); - } - }, - insertAtCaret: function(myValue){ - // Found this at stackoverflow - return this.mirror.each(function(i) { - if (document.selection) { - console.log('IE'); - //For browsers like Internet Explorer - this.focus(); - sel = document.selection.createRange(); - sel.text = myValue; - this.focus(); - } - else if (this.selectionStart || this.selectionStart == '0') { - console.log('FF'); - //For browsers like Firefox and Webkit based - var startPos = this.selectionStart; - var endPos = this.selectionEnd; - var scrollTop = this.scrollTop; - this.value = this.value.substring(0, startPos)+myValue+this.value.substring(endPos,this.value.length); - this.focus(); - this.selectionStart = startPos + myValue.length; - this.selectionEnd = startPos + myValue.length; - this.scrollTop = scrollTop; - } else { - console.log('Smth.'); - this.value += myValue; - this.focus(); - } - }) - }, - showSelection: function() { - var textComponent = this.mirror.get(0); //document.getElementById('Editor'); - var selectedText; - // IE version - if (document.selection != undefined) { - textComponent.focus(); - var sel = document.selection.createRange(); - selectedText = sel.text; - } - // Mozilla version - else if (textComponent.selectionStart != undefined) { - var startPos = textComponent.selectionStart; - var endPos = textComponent.selectionEnd; - selectedText = textComponent.value.substring(startPos, endPos) - } - alert("You selected: " + selectedText); - }, - formatText: function(command, option) { - self = this, useDialog = false; - switch(command) { - case 'ulist': - command = 'insertUnorderedList'; - break; - case 'olist': - command = 'insertOrderedList'; - break; - case 'createlink': - self.showSelection(); - option=prompt('Write the URL here') - useDialog = true; - default: - break; - } - try{ - document.execCommand(command, useDialog, option); - self.dirty = true; // FIXME: This doesn't work because blur is triggered before dirty is set. - self.mirror.trigger('blur'); // Dirty hack to trigger save. Hmm, if it only worked... - }catch(e){ - console.log('Error: ' + e) - } - }, - setEnabled: function(state) { - console.log('function setEnabled: ' + state); - if(state != undefined) { - this._setOption('disabled', !state); - } - return this.options['disabled']; - }, - mode: function(mode) { - if(mode != undefined) { - this._setOption('mode', mode); - } - return this.options['mode']; - }, - /*toggle: function() { - this._setOption('disabled', !this.options['disabled']); - return !this.options['disabled']; - },*/ - toggleMode: function() { - this._setOption('mode', (this.options['mode'] == 'html'?'text':'html')); - return this.options['mode']; - }, - // Use the _setOption method to respond to changes to options - _setOption: function( key, value ) { - console.log('option ' + key + ': ' + value); - switch( key ) { - case 'disabled': - if(value) { - this.mirror.get(0).contenteditable = false; - this.mirror.attr('contenteditable', false); - this.mirror.removeClass('editable'); - this.element.attr('disabled', true); - this.element.removeClass('editable'); - } else { - this.mirror.get(0).contenteditable = true; - this.mirror.attr('contenteditable', true); - this.mirror.addClass('editable'); - this.element.attr('disabled', false); - this.element.addClass('editable'); - } - break; - case 'mode': - switch(value) { - case 'html': - this.mirror.show(); - this.element.hide(); - break; - case 'text': - this.mirror.hide(); - this.element.show(); - this.element.trigger('resize'); - break; - default: - throw { name: 'UnknownMode', message: 'Invalid mode: ' + value } - break; - } - break; - case 'classes': - if($.isArray(value)) { - var mirror = this.mirror; - $.each(this.options['classes'], function(key, value) { - mirror.addClass(value); - }); - } else { - this.mirror.addClass(value); - } - break; - default: - this.options[key] = value; - break; - } - // In jQuery UI 1.8, you have to manually invoke the _setOption method from the base widget - - $.Widget.prototype._setOption.apply( this, arguments ); - // In jQuery UI 1.9 and above, you use the _super method instead - //this._super( "_setOption", key, value ); - }, - // Use the destroy method to clean up any modifications your widget has made to the DOM - destroy: function() { - this.mirror.remove(); - this.element.show(); - // In jQuery UI 1.8, you must invoke the destroy method from the base widget - $.Widget.prototype.destroy.call( this ); - // In jQuery UI 1.9 and above, you would define _destroy instead of destroy and not call the base method - } - -}); - -}( jQuery ) ); - - diff --git a/apps/journal/js/jquery.textchange.js b/apps/journal/js/jquery.textchange.js deleted file mode 100644 index 66a07fc5bc..0000000000 --- a/apps/journal/js/jquery.textchange.js +++ /dev/null @@ -1,76 +0,0 @@ -/*! - * jQuery TextChange Plugin - * http://www.zurb.com/playground/jquery-text-change-custom-event - * - * Copyright 2010, ZURB - * Released under the MIT License - */ -(function ($) { - - $.event.special.textchange = { - - setup: function (data, namespaces) { - $(this).data('lastValue', this.contentEditable === 'true' ? $(this).html() : $(this).val()); - $(this).bind('keyup.textchange', $.event.special.textchange.handler); - $(this).bind('cut.textchange paste.textchange input.textchange', $.event.special.textchange.delayedHandler); - }, - - teardown: function (namespaces) { - $(this).unbind('.textchange'); - }, - - handler: function (event) { - $.event.special.textchange.triggerIfChanged($(this)); - }, - - delayedHandler: function (event) { - var element = $(this); - setTimeout(function () { - $.event.special.textchange.triggerIfChanged(element); - }, 25); - }, - - triggerIfChanged: function (element) { - var current = element[0].contentEditable === 'true' ? element.html() : element.val(); - if (current !== element.data('lastValue')) { - element.trigger('textchange', [element.data('lastValue')]); - element.data('lastValue', current); - } - } - }; - - $.event.special.hastext = { - - setup: function (data, namespaces) { - $(this).bind('textchange', $.event.special.hastext.handler); - }, - - teardown: function (namespaces) { - $(this).unbind('textchange', $.event.special.hastext.handler); - }, - - handler: function (event, lastValue) { - if ((lastValue === '') && lastValue !== $(this).val()) { - $(this).trigger('hastext'); - } - } - }; - - $.event.special.notext = { - - setup: function (data, namespaces) { - $(this).bind('textchange', $.event.special.notext.handler); - }, - - teardown: function (namespaces) { - $(this).unbind('textchange', $.event.special.notext.handler); - }, - - handler: function (event, lastValue) { - if ($(this).val() === '' && $(this).val() !== lastValue) { - $(this).trigger('notext'); - } - } - }; - -})(jQuery); \ No newline at end of file diff --git a/apps/journal/js/settings.js b/apps/journal/js/settings.js deleted file mode 100644 index 8cd1b25f6e..0000000000 --- a/apps/journal/js/settings.js +++ /dev/null @@ -1,15 +0,0 @@ -$(document).ready(function(){ - $('#journal_calendar').on('change', function(event){ - $.post(OC.filePath('journal', 'ajax', 'setdefaultcalendar.php'), {'id':$('#journal_calendar option:selected').val()}, function(jsondata) { - var success = {padding: 0.5em, background-color:green, color: white, font-weight: bold, float: left}; - var failure = {padding: 0.5em, background-color:red, color: white, font-weight: bold, float: left}; - if(jsondata.status == 'success') { - $('#journal_status'); - $('#journal_status').css(success).html(t('journal', 'Saved')).fadeIn().fadeOut(5000); - } else { - $('#journal_status').css(failure); - $('#journal_status').html(t('journal', 'Error saving: ')+jsondata.data.message).fadeIn().fadeOut(5000); - } - }); - }); -}); diff --git a/apps/journal/lib/app.php b/apps/journal/lib/app.php deleted file mode 100644 index d3d9b3bf11..0000000000 --- a/apps/journal/lib/app.php +++ /dev/null @@ -1,135 +0,0 @@ - - * @copyright 2012 Thomas Tanghus - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -/** - * This class manages our journal. - */ -OC_Journal_App::$l10n = new OC_L10N('journal'); -class OC_Journal_App { - public static $l10n; - /* - * @brief categories of the user - */ - protected static $categories = null; - - public static function arrayForJSON($id, $vjournal, $user_timezone) { - // Possible properties: URL - $journal = array( 'id' => $id ); - $journal['summary'] = $vjournal->getAsString('SUMMARY'); - $format = 'text'; - if($vjournal->DESCRIPTION) { - foreach($vjournal->DESCRIPTION->parameters as $parameter){ - if(stripos($parameter->name, 'FORMAT') !== false && stripos($parameter->value, 'HTML') !== false){ - $format = 'html'; // an educated guess ;-) - break; - } - } - $desc = $vjournal->getAsString('DESCRIPTION'); - $journal['description'] = array( - 'value' => ($format=='html'?$body = preg_replace("/.*]*>|<\/body>.*/si", "", $desc):$desc), - 'format' => $format, - 'parameters' => self::parametersForProperty($vjournal->DESCRIPTION) - ); - } else { - $journal['description'] = array('value' => '', 'format' => 'text'); - } - $journal['organizer'] = array( - 'value' => $vjournal->getAsString('ORGANIZER'), - 'parameters' => self::parametersForProperty($vjournal->ORGANIZER) - ); - $journal['categories'] = $vjournal->getAsArray('CATEGORIES'); - //error_log('DTSTART: '.print_r($vjournal->DTSTART, true)); - $dtprop = $vjournal->DTSTART; - if($dtprop) { - $dtstart = $vjournal->DTSTART->getDateTime(); - if($dtstart) { - //if(!) - $tz = new DateTimeZone($user_timezone); - if($tz->getName() != $dtstart->getTimezone()->getName() && !$vjournal->DTSTART->offsetExists('TZID')) { - //error_log($tz->getName().' != '.$dtstart->getTimezone()->getName()); - //error_log('TZ offset: '.$tz->getOffset(new DateTime("now"))/60); - $dtstart->setTimezone($tz); - } - $journal['dtstart'] = $dtstart->format('U'); - $journal['only_date'] = ($dtprop->getDateType() == Sabre_VObject_Property_DateTime::DATE); - } else { - OCP\Util::writeLog('journal', 'Could not get DTSTART DateTime for '.$journal['summary'], OCP\Util::ERROR); - } - } else { - OCP\Util::writeLog('journal', 'Could not get DTSTART for '.$journal['summary'], OCP\Util::ERROR); - } - return $journal; - } - - /** Get a map of a properties parameters for JSON - * @param $property Sabre_VObject_Property - * @return array of parameters in { name => value, } format - */ - public static function parametersForProperty($property) { - $temp = array(); - if(!$property) { - return; - } - foreach($property->parameters as $parameter){ - $temp[$parameter->name] = $parameter->value; - } - return $temp; - } - - /* - * @brief returns the vcategories object of the user - * @return (object) $vcategories - */ - protected static function getVCategories() { - if (is_null(self::$categories)) { - self::$categories = new OC_VCategories('calendar'); - } - return self::$categories; - } - - - /** - * Create a stub for a new journal entry. - * @return OC_VObject The newly created stub. - */ - public static function createVCalendar() { - $vcalendar = new OC_VObject('VCALENDAR'); - $appinfo = OCP\App::getAppInfo('journal'); - $appversion = OCP\App::getAppVersion('journal'); - $prodid = '-//ownCloud//NONSGML '.$appinfo['name'].' '.$appversion.'//EN'; - $vcalendar->add('PRODID', $prodid); - $vcalendar->add('VERSION', '2.0'); - - $vjournal = new OC_VObject('VJOURNAL'); - $vjournal->setDateTime('DTSTART', 'now', Sabre_VObject_Property_DateTime::LOCALTZ); - $vjournal->setDateTime('CREATED', 'now', Sabre_VObject_Property_DateTime::UTC); - $vjournal->setUID(); - $email = OCP\Config::getUserValue(OCP\User::getUser(), 'settings', 'email', ''); - if($email) { - $vjournal->setString('ORGANIZER', 'mailto:'.$email); - } - $vcalendar->add($vjournal); - return $vcalendar; - } - -} diff --git a/apps/journal/lib/hooks.php b/apps/journal/lib/hooks.php deleted file mode 100644 index 2298871148..0000000000 --- a/apps/journal/lib/hooks.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -/** - * This class manages our journal. - */ -class OC_Journal_Hooks { - /** - * Hook to convert a completed Task (VTODO) to a journal entry and add it to the calendar. - * @param $vtodo An OC_VObject of type VTODO. - */ - public static function taskToJournalEntry($vtodo) { - if(!$vtodo) { return; } - - OCP\Util::writeLog('journal', 'Completed task: '.$vtodo->getAsString('SUMMARY'), OCP\Util::DEBUG); - $vcalendar = OC_Journal_App::createVCalendar(); - $vjournal = $vcalendar->VJOURNAL; - $vjournal->setDateTime('DTSTART',$vtodo->COMPLETED->getDateTime()); - $vjournal->SUMMARY = $vtodo->SUMMARY; - $vjournal->setString('SUMMARY', OC_Journal_App::$l10n->t('Completed task: ').$vjournal->getAsString('SUMMARY')); - $vjournal->DESCRIPTION = $vtodo->DESCRIPTION; - - $cid = OCP\Config::getUserValue(OCP\User::getUser(), 'journal', 'default_calendar', null); - if(!$cid) { - $calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); - $first_calendar = reset($calendars); - $cid = $first_calendar['id']; - } - try { - $id = OC_Calendar_Object::add($cid, $vcalendar->serialize()); - } catch (Exception $e) { - OCP\Util::writeLog('journal', 'Error adding completed Task to calendar: "'.$cid.'" '. $e->getMessage(), OCP\Util::ERROR); - } - } -} diff --git a/apps/journal/lib/search.php b/apps/journal/lib/search.php deleted file mode 100644 index 27b9b87b03..0000000000 --- a/apps/journal/lib/search.php +++ /dev/null @@ -1,45 +0,0 @@ - 0) { - $searchquery = explode(' ', $query); - }else{ - $searchquery[] = $query; - } - error_log('search'); - $user_timezone = OCP\Config::getUserValue(OCP\USER::getUser(), 'calendar', 'timezone', date_default_timezone_get()); - $l = new OC_l10n('journal'); - foreach($calendars as $calendar) { - $objects = OC_Calendar_Object::all($calendar['id']); - foreach($objects as $object) { - if($object['objecttype']!='VJOURNAL') { - continue; - } - if(substr_count(strtolower($object['summary']), strtolower($query)) > 0) { - $calendardata = OC_VObject::parse($object['calendardata']); - $vjournal = $calendardata->VJOURNAL; - $dtstart = $vjournal->DTSTART; - if($dtstart) { - continue; - } - $start_dt = $dtstart->getDateTime(); - $start_dt->setTimezone(new DateTimeZone($user_timezone)); - if ($dtstart->getDateType() == Sabre_VObject_Property_DateTime::DATE) { - $info = $l->t('Date') . ': ' . $start_dt->format('d.m.Y'); - }else{ - $info = $l->t('Date') . ': ' . $start_dt->format('d.m.y H:i'); - } - $link = OCP\Util::linkTo('journal', 'index.php').'&id='.urlencode($object['id']); - $results[]=new OC_Search_Result($object['summary'],$info, $link,(string)$l->t('Journal'));//$name,$text,$link,$type - } - } - } - return $results; - } -} diff --git a/apps/journal/lib/vjournal.php b/apps/journal/lib/vjournal.php deleted file mode 100644 index b9aedea041..0000000000 --- a/apps/journal/lib/vjournal.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AFFERO GENERAL PUBLIC LICENSE for more details. - * - * You should have received a copy of the GNU Affero General Public - * License along with this library. If not, see . - * - */ - -/** - * This class manages our journals - */ -class OC_Task_VJournal extends OC_Calendar_Object{ -} diff --git a/apps/journal/settings.php b/apps/journal/settings.php deleted file mode 100644 index 35f0ee7d6c..0000000000 --- a/apps/journal/settings.php +++ /dev/null @@ -1,45 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); - -$errors = array(); - -$required_apps = array( - array('id' => 'tal', 'name' => 'TAL Page Templates'), - array('id' => 'journal', 'name' => 'Journal'), - array('id' => 'contacts', 'name' => 'Contacts'), -); -foreach($required_apps as $app) { - if(!OCP\App::isEnabled($app['id'])) { - $error = (string)$l->t('The %%s app isn\'t enabled! Please enable it here: Enable %%s app'); - $errors[] = sprintf($error, $app['name'],OCP\Util::linkTo('settings', 'apps'), $app['id'], $app['name']); - } -} - -$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); -if( count($calendars) == 0 ) { - $error = (string)$l->t('You have no calendars. Please add one at the Calendar app'); - $errors[] = sprintf($error, OCP\Util::linkTo('calendar', 'index.php')); -} - -if(count($errors) > 0) { - $tmpl = new OCP\Template('journal', 'rtfm'); - $tmpl->assign('errors',$errors, false); -} else { - $cid = OCP\Config::getUserValue(OCP\User::getUser(), 'journal', 'default_calendar', null); - OCP\Util::addScript('journal', 'settings'); - $tmpl = new OC_TALTemplate('journal', 'settings', 'user'); - $tmpl->assign('calendars', $calendars); - $tmpl->assign('cid', $cid); -} - -return $tmpl->fetchPage(); - -?> diff --git a/apps/journal/templates/index.pt b/apps/journal/templates/index.pt deleted file mode 100644 index 40ce351a54..0000000000 --- a/apps/journal/templates/index.pt +++ /dev/null @@ -1,101 +0,0 @@ - - - - Journal - - -
    -
    -
    - - -
    -
      -
      -
      - -
        -
      • - -
      • -
      • - -
      • -
      • - -
      • -
      • - -
      • -
      • - -
      • -
      • - -
      • -
      • -
      -
      -
      -
      -
      - - - - - - - - - - - -
      -
      -
      - -
      -
      -
      - - - - -
      -
      - - - -
      -
      - - -
      -
      -
      - -
      -
      - - \ No newline at end of file diff --git a/apps/journal/templates/rtfm.php b/apps/journal/templates/rtfm.php deleted file mode 100644 index 8fd51fb8d0..0000000000 --- a/apps/journal/templates/rtfm.php +++ /dev/null @@ -1,7 +0,0 @@ -
        - -
      • - -
      - diff --git a/apps/journal/templates/settings.pt b/apps/journal/templates/settings.pt deleted file mode 100644 index 3e788f5881..0000000000 --- a/apps/journal/templates/settings.pt +++ /dev/null @@ -1,15 +0,0 @@ -
      -
      - Journal -
      -
      Select default calendar
      for storing journals
      -
      - -
      -
      -
      -
      diff --git a/apps/news/.gitignore b/apps/news/.gitignore deleted file mode 100644 index 16469399de..0000000000 --- a/apps/news/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -3rdparty/* -news.kdev4 -*~ -.kdev4 -img/* diff --git a/apps/news/ajax/createfeed.php b/apps/news/ajax/createfeed.php deleted file mode 100644 index 754d874957..0000000000 --- a/apps/news/ajax/createfeed.php +++ /dev/null @@ -1,37 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('news'); -OCP\JSON::callCheck(); - -$userid = OCP\USER::getUser(); - -$feedurl = trim($_POST['feedurl']); -$folderid = trim($_POST['folderid']); - -$feed = OC_News_Utils::fetch($feedurl); -$feedmapper = new OC_News_FeedMapper(); -$feedid = $feedmapper->save($feed, $folderid); - -$l = OC_L10N::get('news'); - -if(!$feedid) { - OCP\JSON::error(array('data' => array('message' => $l->t('Error adding folder.')))); - OCP\Util::writeLog('news','ajax/createfeed.php: Error adding feed: '.$_POST['feedurl'], OCP\Util::ERROR); - exit(); -} - -//TODO: replace the following with a real success case. see contact/ajax/createaddressbook.php for inspirations -OCP\JSON::success(array('data' => array('message' => $l->t('Feed added!')))); - diff --git a/apps/news/ajax/createfolder.php b/apps/news/ajax/createfolder.php deleted file mode 100644 index b5f624604d..0000000000 --- a/apps/news/ajax/createfolder.php +++ /dev/null @@ -1,41 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('news'); -OCP\JSON::callCheck(); - -$userid = OCP\USER::getUser(); - -$name = trim($_POST['name']); -$parentid = trim($_POST['parentid']); - -$foldermapper = new OC_News_FolderMapper($userid); - -if($parentid != 0) - $folder = new OC_News_Folder($name, NULL, $foldermapper->find($parentid)); -else - $folder = new OC_News_Folder($name); - -$folderid = $foldermapper->save($folder); - -$l = OC_L10N::get('news'); - -if(!$folderid) { - OCP\JSON::error(array('data' => array('message' => $l->t('Error adding folder.')))); - OCP\Util::writeLog('news','ajax/createfolder.php: Error adding folder: '.$_POST['name'], OCP\Util::ERROR); -} -else { - //TODO: replace the following with a real success case. see contact/ajax/createaddressbook.php for inspirations - OCP\JSON::success(array('data' => array('message' => $l->t('Folder added!')))); -} \ No newline at end of file diff --git a/apps/news/ajax/deletefeed.php b/apps/news/ajax/deletefeed.php deleted file mode 100644 index d31a9417d1..0000000000 --- a/apps/news/ajax/deletefeed.php +++ /dev/null @@ -1,33 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('news'); -OCP\JSON::callCheck(); - -$userid = OCP\USER::getUser(); - -$feedid = $_POST['feedid']; - -$feedmapper = new OC_News_FeedMapper(); -$success = $feedmapper->deleteById($feedid); - -$l = OC_L10N::get('news'); - -if(!$success) { - OCP\JSON::error(array('data' => array('message' => $l->t('Error removing feed.')))); - OCP\Util::writeLog('news','ajax/deletefeed.php: Error removing feed: '.$_POST['feedid'], OCP\Util::ERROR); - exit(); -} - -OCP\JSON::success(array('data' => array( 'feedid' => $feedid ))); diff --git a/apps/news/ajax/deletefolder.php b/apps/news/ajax/deletefolder.php deleted file mode 100644 index bf975c6c32..0000000000 --- a/apps/news/ajax/deletefolder.php +++ /dev/null @@ -1,33 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('news'); -OCP\JSON::callCheck(); - -$userid = OCP\USER::getUser(); - -$folderid = trim($_POST['folderid']); - -$foldermapper = new OC_News_FolderMapper(); -$success = $foldermapper->deleteById($folderid); - -$l = OC_L10N::get('news'); - -if(!$success) { - OCP\JSON::error(array('data' => array('message' => $l->t('Error removing folder.')))); - OCP\Util::writeLog('news','ajax/deletefolder.php: Error removing folder: '.$_POST['folderid'], OCP\Util::ERROR); - exit(); -} - -OCP\JSON::success(array('data' => array( 'folderid' => $folderid ))); diff --git a/apps/news/ajax/feeddialog.php b/apps/news/ajax/feeddialog.php deleted file mode 100644 index c42771c988..0000000000 --- a/apps/news/ajax/feeddialog.php +++ /dev/null @@ -1,7 +0,0 @@ - assign('allfeeds', $allfeeds); -$output -> printpage(); \ No newline at end of file diff --git a/apps/news/ajax/folderdialog.php b/apps/news/ajax/folderdialog.php deleted file mode 100644 index 97b679e662..0000000000 --- a/apps/news/ajax/folderdialog.php +++ /dev/null @@ -1,7 +0,0 @@ - assign('allfeeds', $allfeeds); -$output -> printpage(); \ No newline at end of file diff --git a/apps/news/ajax/markitem.php b/apps/news/ajax/markitem.php deleted file mode 100644 index c42dc9350c..0000000000 --- a/apps/news/ajax/markitem.php +++ /dev/null @@ -1,35 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('news'); -OCP\JSON::callCheck(); - -$itemid = $_POST['itemid']; - -$itemmapper = new OC_News_ItemMapper(); -$item = $itemmapper->find($itemid); -$item->setRead(); -$success = $itemmapper->update($item); - -$l = OC_L10N::get('news'); - -if(!$success) { - OCP\JSON::error(array('data' => array('message' => $l->t('Error marking item as read.')))); - OCP\Util::writeLog('news','ajax/markitem.php: Error marking item as read: '.$_POST['itemid'], OCP\Util::ERROR); - exit(); -} - -//TODO: replace the following with a real success case. see contact/ajax/createaddressbook.php for inspirations -OCP\JSON::success(array('data' => array('itemid' => $itemid ))); - diff --git a/apps/news/ajax/populateroot.php b/apps/news/ajax/populateroot.php deleted file mode 100644 index a408c25ec5..0000000000 --- a/apps/news/ajax/populateroot.php +++ /dev/null @@ -1,18 +0,0 @@ -populate('Everything', 0); - -if ($allfeeds) { - $feedid = isset( $_GET['feedid'] ) ? $_GET['feedid'] : null; - if ($feedid == null) { - - } -} -else { - $feedid = 0; -} diff --git a/apps/news/appinfo/app.php b/apps/news/appinfo/app.php deleted file mode 100644 index eb1b54455d..0000000000 --- a/apps/news/appinfo/app.php +++ /dev/null @@ -1,42 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -OC::$CLASSPATH['OC_News_Item'] = 'apps/news/lib/item.php'; -OC::$CLASSPATH['OC_News_Collection'] = 'apps/news/lib/collection.php'; -OC::$CLASSPATH['OC_News_Feed'] = 'apps/news/lib/feed.php'; -OC::$CLASSPATH['OC_News_Folder'] = 'apps/news/lib/folder.php'; - -OC::$CLASSPATH['OC_News_FeedMapper'] = 'apps/news/lib/feedmapper.php'; -OC::$CLASSPATH['OC_News_ItemMapper'] = 'apps/news/lib/itemmapper.php'; -OC::$CLASSPATH['OC_News_FolderMapper'] = 'apps/news/lib/foldermapper.php'; - -OC::$CLASSPATH['OC_News_Utils'] = 'apps/news/lib/utils.php'; - - -$l = new OC_l10n('news'); - -OCP\App::registerPersonal('news', 'settings'); - -OCP\App::register( array( - 'order' => 70, - 'id' => 'news', - 'name' => 'News' -)); - -OCP\App::addNavigationEntry( array( - 'id' => 'news', - 'order' => 74, - 'href' => OC_Helper::linkTo( 'news', 'index.php' ), - 'icon' => OC_Helper::imagePath( 'news', 'icon.svg' ), - 'name' => $l->t('News') -)); - diff --git a/apps/news/appinfo/database.xml b/apps/news/appinfo/database.xml deleted file mode 100644 index 3f5f6c44af..0000000000 --- a/apps/news/appinfo/database.xml +++ /dev/null @@ -1,186 +0,0 @@ - - - *dbname* - true - false - latin1 - - *dbprefix*news_folders - - - id - integer - 0 - true - 1 - 4 - - - parent_id - integer - false - 4 - - - name - text - true - 100 - - - user_id - text - - true - 64 - - - - folder_id - true - - id - descending - - - - user_id - - user_id - - - -
      - - - *dbprefix*news_feeds - - - id - integer - 0 - true - 1 - 4 - - - url - text - true - 100 - - - title - text - true - 100 - - - added - integer - - false - true - 4 - - - lastmodified - integer - - false - true - 4 - - - folder_id - integer - true - 4 - - - - feed_id - true - true - - id - descending - - - - - feed_url - true - false - - url - - - -
      - - - *dbprefix*news_items - - - id - integer - 0 - true - 1 - 4 - - - guid - text - true - 100 - - - url - text - 100 - - - title - text - 100 - - - feed_id - integer - true - 4 - - - body - text - 4000 - - - status - integer - 1 - - - - item_id - true - - id - descending - - - - item_guid - true - - guid - - - feed_id - - - -
      -
      diff --git a/apps/news/appinfo/info.xml b/apps/news/appinfo/info.xml deleted file mode 100644 index 0ada6e75c0..0000000000 --- a/apps/news/appinfo/info.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - news - News - An RSS/Atom feed reader - 5.5 - AGPL - Alessandro Cosentino - 4 - diff --git a/apps/news/css/news.css b/apps/news/css/news.css deleted file mode 100644 index 04ce0d2e73..0000000000 --- a/apps/news/css/news.css +++ /dev/null @@ -1,52 +0,0 @@ -li { padding-right: 0px !important; } - -.collapsable { background: url('%webroot%/core/img/places/folder.svg') no-repeat left center; padding-left: 20px;} -.news_input { float:left; font-size:12px; padding:4px 2px; border:solid 1px #aacfe4; width:200px; } -.svg { border: inherit; background: inherit; } - -#leftcontent { top: 3.5em !important; padding: 0; margin: 0; } -#rightcontent { top: 3.5em !important; padding-top: 5px; } -#feeds { background: #fff; width: 20em; left: 12.5em; top: 3.7em; bottom:3em; position: fixed; overflow: auto; padding: 0; margin: 0; } -/* #feeds a { height: 23px; display: block; margin: 0 0 0 0; padding: 0 0 0 25px; } */ -#bottomcontrols { padding: 0; bottom:0px; overflow:visible; height:2.8em; width: 20em; margin:0; background:#eee; border-top:1px solid #ccc; position:fixed; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;} -#feeds_delete { position: absolute; right: 0px; background: url('%webroot%/core/img/actions/delete.svg') no-repeat center; display: inline; } -#feeds_edit { position: absolute; right: 1.6em; background: url('%webroot%/core/img/actions/rename.svg') no-repeat center; display: inline; } - -#dropdownBtn { width: 9em; padding-left: 0; padding-right:20px; background: url('%webroot%/core/img/actions/triangle-s.svg') no-repeat right center; } - -#addfolder { background: url('%webroot%/core/img/places/folder.svg') no-repeat left center; padding-left: 20px; } -#addfeed { background: url('%appswebroot%/apps/news/img/rss.svg') no-repeat left center; padding-left: 20px; } - -ul.controls li { float: left; } - -.accordion .title_unread { background: #DCDCDC; font-size: 12px; border-bottom:1px solid #ccc; font-weight:bold;} -.accordion .title_read { background: #DCDCDC; font-size: 12px; border-bottom:1px solid #ccc;} - -ul.menu { position: absolute; z-index:100; margin-left: 0.3em; - display: none; - background:#EEEEEE; /* default background for browsers without gradient support */ - /* css3 */ - background:-webkit-gradient(linear, 0 0, 0 100%, from(#DCDCDC), to(#EEEEEE)); - background:-moz-linear-gradient(#DCDCDC, #EEEEEE); - background:-o-linear-gradient(#DCDCDC, #EEEEEE); - background:linear-gradient(#DCDCDC, #EEEEEE); - /* - -webkit-border-radius:10px; - -moz-border-radius:10px; - border-radius:10px; - */ -} - -ul#dropdownmenu { left: 0em; box-shadow: 0px 0px 10px rgb(0, 0, 0); } - -ul#feedfoldermenu { position:fixed; margin-left: 0; bottom: 2.8em; border-left:1px solid #ccc; border-top:1px solid #ccc; border-right:1px solid #ccc; -moz-box-shadow: 0 -3px 3px -3px #000; -webkit-box-shadow: 0 -3px 3px -3px #000; box-shadow: 0 -3px 3px -3px #000;} - -li.menuItem { margin-left:0.7em; margin-right:0.7em; float: none !important; text-align: left; } - -li.folder_list:hover { color: rgb(0, 0, 0) !important; background: none !important; } -li.feeds_list:hover { background: none repeat scroll 0% 0% rgb(221, 221, 221) !important; } -div.collapsable:hover { background-color: rgb(221, 221, 221); } -div.add_parentfolder { position: relative; } - -div.dialog { overflow: visible; } - diff --git a/apps/news/index.php b/apps/news/index.php deleted file mode 100644 index e75ec19d67..0000000000 --- a/apps/news/index.php +++ /dev/null @@ -1,44 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// Check if we are a user -OCP\User::checkLoggedIn(); - -OCP\App::checkAppEnabled('news'); -OCP\App::setActiveNavigationEntry('news'); - -OCP\Util::addscript('news','news'); -OCP\Util::addStyle('news','news'); - -$l = OC_L10N::get('news'); - -$foldermapper = new OC_News_FolderMapper(OCP\USER::getUser()); - -$allfeeds = $foldermapper->populate($l->t('Everything'), 0); - -if ($allfeeds) { - $feedid = isset( $_GET['feedid'] ) ? $_GET['feedid'] : null; - if ($feedid == null) { - - } -} -else { - $feedid = 0; -} - -$tmpl = new OCP\Template( 'news', 'main', 'user' ); -$tmpl->assign('allfeeds', $allfeeds); -$tmpl->assign('feedid', $feedid); -$tmpl->printPage(); - -?> diff --git a/apps/news/js/news.js b/apps/news/js/news.js deleted file mode 100644 index 96c3f60b7d..0000000000 --- a/apps/news/js/news.js +++ /dev/null @@ -1,196 +0,0 @@ -News={ - DropDownMenu: { - fade:function(menu){ - var list = $(menu).toggle(); - return false; - }, - dropdown:function(button){ - var list = $(button).parent().find('ul#dropdownmenu'); - if (list.css('display') == 'none') - list.slideDown('fast').show(); - else - list.slideUp('fast'); - - return false; - }, - selectItem:function(item, folderid){ - var parent = $(item).parent().parent(); - parent.find('#dropdownBtn').text($(item).text()); - parent.find(':input[name="folderid"]').val(folderid); - parent.find('ul#dropdownmenu').slideUp('fast'); - } - }, - UI: { - overview:function(dialogtype, dialogfile){ - if($(dialogtype).dialog('isOpen') == true){ - $(dialogtype).dialog('moveToTop'); - }else{ - $('#dialog_holder').load(OC.filePath('news', 'ajax', dialogfile), function(jsondata){ - if(jsondata.status != 'error'){ - $(dialogtype).dialog({ - dialogClass:'dialog', - minWidth: 600, - close: function(event, ui) { - $(this).dialog('destroy').remove(); - } - }).css('overflow','visible'); - } else { - alert(jsondata.data.message); - } - }); - } - return false; - } - }, - Folder: { - submit:function(button){ - var displayname = $("#folder_add_name").val().trim(); - - if(displayname.length == 0) { - OC.dialogs.alert(t('news', 'Displayname cannot be empty.'), t('news', 'Error')); - return false; - } - - $(button).attr("disabled", true); - //translation here!!! - $(button).prop('value', 'Adding...'); - - var folderid = $('#inputfolderid:input[name="folderid"]').val(); - - var url; - url = OC.filePath('news', 'ajax', 'createfolder.php'); - - $.post(url, { name: displayname, parentid: folderid }, - function(jsondata){ - if(jsondata.status == 'success'){ - //$(button).closest('tr').prev().html(jsondata.page).show().next().remove(); - OC.dialogs.alert(jsondata.data.message, t('news', 'Success!')); - } else { - OC.dialogs.alert(jsondata.data.message, t('news', 'Error')); - } - $("#folder_add_name").val(''); - $(button).attr("disabled", false); - //translation here!!! - $(button).prop('value', 'Add folder'); - }); - }, - 'delete':function(folderid) { - $('#feeds_delete').tipsy('hide'); - OC.dialogs.confirm(t('news', 'Are you sure you want to delete this folder and all its feeds?'), t('news', 'Warning'), function(answer) { - if(answer == true) { - $.post(OC.filePath('news', 'ajax', 'deletefolder.php'),{'folderid':folderid},function(jsondata){ - if(jsondata.status == 'success'){ - alert('removed!'); - } - else{ - OC.dialogs.alert(jsondata.data.message, t('news', 'Error')); - } - }); - } - }); - return false; - } - }, - Feed: { - id:'', - submit:function(button){ - var feedurl = $("#feed_add_url").val().trim(); - - if(feedurl.length == 0) { - OC.dialogs.alert(t('news', 'URL cannot be empty.'), t('news', 'Error')); - return false; - } - - $(button).attr("disabled", true); - //translation here!!! - $(button).prop('value', 'Adding...'); - - var folderid = $('#inputfolderid:input[name="folderid"]').val(); - - var url; - url = OC.filePath('news', 'ajax', 'createfeed.php'); - - $.post(url, { feedurl: feedurl, folderid: folderid }, - function(jsondata){ - if(jsondata.status == 'success'){ - OC.dialogs.alert(jsondata.data.message, t('news', 'Success!')); - } else { - OC.dialogs.alert(jsondata.data.message, t('news', 'Error')); - } - $("#feed_add_url").val(''); - $(button).attr("disabled", false); - //translation here!!! - $(button).prop('value', 'Add feed'); - }); - }, - 'delete':function(feedid) { - $('#feeds_delete').tipsy('hide'); - OC.dialogs.confirm(t('news', 'Are you sure you want to delete this feed?'), t('news', 'Warning'), function(answer) { - if(answer == true) { - $.post(OC.filePath('news', 'ajax', 'deletefeed.php'),{'feedid':feedid},function(jsondata){ - if(jsondata.status == 'success'){ - $('#leftcontent [data-id="'+jsondata.data.feedid+'"]').remove(); - //change the right view too (maybe a message to subscribe, like in Google Reader?) - } - else{ - OC.dialogs.alert(jsondata.data.message, t('news', 'Error')); - } - }); - } - }); - return false; - }, - markItem:function(itemid) { - $.post(OC.filePath('news', 'ajax', 'markitem.php'),{'itemid':itemid},function(jsondata){ - if(jsondata.status == 'success'){ - var $currentitem = $('#rightcontent [data-id="'+jsondata.data.itemid+'"]'); - $currentitem.removeClass('title_unread'); - $currentitem.addClass('title_read'); - //set a timeout for this - } - else{ - OC.dialogs.alert(jsondata.data.message, t('news', 'Error')); - } - }); - } - } -} - -$(document).ready(function(){ - - $('#addfeed').click(function() { - News.UI.overview('#addfeed_dialog','feeddialog.php'); - $(this).parent().toggle(); - }); - $('#addfolder').click(function() { - News.UI.overview('#addfolder_dialog','folderdialog.php'); - $(this).parent().toggle(); - }); - - $('.collapsable').click(function(){ - $(this).parent().children().toggle(); - $(this).toggle(); - }); - - $('.accordion .title_unread').click(function() { - $(this).next().toggle(); - return false; - }).next().hide(); - - $('.accordion .title_read').click(function() { - $(this).next().toggle(); - return false; - }).next().hide(); - - var list = $('.collapsable,.feeds_list').hover(function() { - var elem = $(this).find('#feeds_delete,#feeds_edit'); - if(elem.css('display') == 'none') - elem.css('display', 'inline'); - else - elem.css('display', 'none'); - - return false; - }); - list.find('#feeds_delete').hide(); - list.find('#feeds_edit').hide(); -}); diff --git a/apps/news/js/settings.js b/apps/news/js/settings.js deleted file mode 100644 index 4c645d241e..0000000000 --- a/apps/news/js/settings.js +++ /dev/null @@ -1,15 +0,0 @@ -$(document).ready(function(){ - - - - $('#somesetting').blur(function(event){ - event.preventDefault(); - var post = $( "#somesetting" ).serialize(); - $.post( OC.filePath('apptemplate','ajax','seturl.php') , post, function(data){ OC.msg.finishedSaving('#somesetting .msg', data); }); - }); - - - -}); - - diff --git a/apps/news/lib/collection.php b/apps/news/lib/collection.php deleted file mode 100644 index 2ebbb646f0..0000000000 --- a/apps/news/lib/collection.php +++ /dev/null @@ -1,32 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class models a collection, which is either a feed or a folder. - */ -class OC_News_Collection { - - private $id; - - public function __construct($id){ - $this->id = $id; - } - - public function getId(){ - return $this->id; - } - - public function setId($id){ - $this->id = $id; - } - -} \ No newline at end of file diff --git a/apps/news/lib/feed.php b/apps/news/lib/feed.php deleted file mode 100644 index bbed8d5982..0000000000 --- a/apps/news/lib/feed.php +++ /dev/null @@ -1,46 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class models a feed. - */ -class OC_News_Feed extends OC_News_Collection { - - private $url; - private $spfeed; //encapsulate a SimplePie_Core object - private $items; //array that contains all the items of the feed - - public function __construct($url, $title, $items, $id = null){ - $this->url = $url; - $this->title = $title; - $this->items = $items; - if ($id !== null){ - parent::__construct($id); - } - } - - public function getUrl(){ - return $this->url; - } - - public function getTitle(){ - return $this->title; - } - - public function setItems($items){ - $this->items = $items; - } - - public function getItems(){ - return $this->items; - } -} diff --git a/apps/news/lib/feedmapper.php b/apps/news/lib/feedmapper.php deleted file mode 100644 index 73afa0e864..0000000000 --- a/apps/news/lib/feedmapper.php +++ /dev/null @@ -1,182 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class maps a feed to an entry in the feeds table of the database. - */ -class OC_News_FeedMapper { - - const tableName = '*PREFIX*news_feeds'; - - /** - * @brief Retrieve a feed from the database - * @param id The id of the feed in the database table. - * @returns - */ - public function findById($id){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE id = ?'); - $result = $stmt->execute(array($id)); - $row = $result->fetchRow(); - $url = $row['url']; - $title = $row['title']; - $feed = new OC_News_Feed($url, $title, null, $id); - return $feed; - } - - /** - * @brief Retrieve a feed from the database - * @param id The id of the feed in the database table. - * @returns - */ - public function findByFolderId($folderid){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE folder_id = ?'); - $result = $stmt->execute(array($folderid)); - $feeds = array(); - while ($row = $result->fetchRow()) { - $url = $row['url']; - $title = $row['title']; - $id = $row['id']; - $feed = new OC_News_Feed($url, $title, null, $id); - $feeds[] = $feed; - } - return $feeds; - } - - - /** - * @brief Retrieve a feed and all its items from the database - * @param id The id of the feed in the database table. - * @returns - */ - public function findWithItems($id){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE id = ?'); - $result = $stmt->execute(array($id)); - $row = $result->fetchRow(); - $url = $row['url']; - $title = $row['title']; - $feed = new OC_News_Feed($url, $title, null,$id); - - $itemMapper = new OC_News_ItemMapper(); - $items = $itemMapper->findAll($id); - $feed->setItems($items); - - return $feed; - } - - /** - * @brief Find the id of a feed and all its items from the database - * @param url url of the feed - * @return id of the feed corresponding to the url passed as parameters - * null - if there is no such feed - */ - public function findIdFromUrl($url){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE url = ?'); - $result = $stmt->execute(array($url)); - $row = $result->fetchRow(); - $id = null; - if ($row != null){ - $id = $row['id']; - } - return $id; - } - - /** - * @brief Save the feed and all its items into the database - * @param feed the feed to be saved - * @returns The id of the feed in the database table. - */ - //TODO: handle error case - public function save(OC_News_Feed $feed, $folderid){ - $CONFIG_DBTYPE = OCP\Config::getSystemValue( "dbtype", "sqlite" ); - if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){ - $_ut = "strftime('%s','now')"; - } elseif($CONFIG_DBTYPE == 'pgsql') { - $_ut = 'date_part(\'epoch\',now())::integer'; - } else { - $_ut = "UNIX_TIMESTAMP()"; - } - - $title = $feed->getTitle(); - $url = htmlspecialchars_decode($feed->getUrl()); - - if(empty($title)) { - $l = OC_L10N::get('news'); - $title = $l->t('no title'); - } - - //FIXME: Detect when feed contains already a database id - $feedid = $this->findIdFromUrl($url); - if ($feedid == null){ - $query = OCP\DB::prepare(' - INSERT INTO ' . self::tableName . - '(url, title, folder_id, added, lastmodified) - VALUES (?, ?, ?, ?, ?) - '); - - $params=array( - $url, - htmlspecialchars_decode($title), - $folderid, - $_ut, - $_ut - ); - $query->execute($params); - - $feedid = OCP\DB::insertid(self::tableName); - } - $feed->setId($feedid); - - $itemMapper = new OC_News_ItemMapper(); - - $items = $feed->getItems(); - foreach($items as $item){ - $itemMapper->save($item, $feedid); - } - - return $feedid; - } - - public function deleteById($id){ - if ($id == null) { - return false; - } - $stmt = OCP\DB::prepare('DELETE FROM ' . self::tableName .' WHERE id = ?'); - - $result = $stmt->execute(array($id)); - - $itemMapper = new OC_News_ItemMapper(); - //TODO: handle the value that the execute returns - $itemMapper->deleteAll($id); - - return true; - } - public function delete(OC_News_Feed $feed){ - $id = $feed->getId(); - return deleteById($id); - } - - //it's more complicated tan this...recursive delete, or delete with a join - public function deleteAll($folderdid){ - if ($folderid == null) { - return false; - } - $stmt = OCP\DB::prepare('DELETE FROM ' . self::tableName .' WHERE folder_id = ?'); - - $result = $stmt->execute(array($folderid)); - - $itemMapper = new OC_News_ItemMapper(); - //TODO: handle the value that the execute returns - $itemMapper->deleteAll($id); - - return true; - } -} \ No newline at end of file diff --git a/apps/news/lib/folder.php b/apps/news/lib/folder.php deleted file mode 100644 index 6654b2f5e9..0000000000 --- a/apps/news/lib/folder.php +++ /dev/null @@ -1,56 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class models a folder that contains feeds. - */ -class OC_News_Folder extends OC_News_Collection { - - private $name; - private $children; - private $parent; - - public function __construct($name, $id = null, OC_News_Collection $parent = null){ - $this->name = $name; - if ($id !== null){ - parent::__construct($id); - } - $this->children = array(); - if ($parent !== null){ - $this->parent = $parent; - } - } - - public function getName(){ - return $this->name; - } - - public function setName($name){ - $this->name = $name; - } - - public function getParentId(){ - if ($this->parent === null){ - return 0; - } - return $this->parent->getId(); - } - - public function addChild(OC_News_Collection $child){ - $this->children[] = $child; - } - - public function getChildren(){ - return $this->children; - } - -} \ No newline at end of file diff --git a/apps/news/lib/foldermapper.php b/apps/news/lib/foldermapper.php deleted file mode 100644 index 45dc53c424..0000000000 --- a/apps/news/lib/foldermapper.php +++ /dev/null @@ -1,148 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class maps a feed to an entry in the feeds table of the database. - */ -class OC_News_FolderMapper { - - const tableName = '*PREFIX*news_folders'; - - private $userid; - - public function __construct($userid = null){ - if ($userid !== null) { - $this->userid = $userid; - } - $userid = OCP\USER::getUser(); - } - - /** - * @brief Create a folder and populate with children from the database - * @param id The id of the folder. - * @param name The name of the folder. - * @returns an instance of OC_News_Folder - */ - public function populate($name, $id){ - $root = new OC_News_Folder($name, $id); - $stmt = OCP\DB::prepare('SELECT * - FROM ' . self::tableName . - ' WHERE user_id = ? AND parent_id = ?'); - $result = $stmt->execute(array($this->userid, $id)); - - while( $row = $result->fetchRow()){ - $child = OC_News_FolderMapper::populate($row['name'], $row['id']); - $root->addChild($child); - } - - $feedmapper = new OC_News_FeedMapper(); - $feeds = $feedmapper->findByFolderId($id); - foreach ($feeds as $feed){ - $root->addChild($feed); - } - - return $root; - } - - /** - * @brief Retrieve a folder from the database - * @param id The id of the folder in the database table. - * @returns an instance of OC_News_Folder - */ - public function find($id){ - $stmt = OCP\DB::prepare('SELECT * - FROM ' . self::tableName . - ' WHERE user_id = ? AND id = ?'); - $result = $stmt->execute(array($this->userid, $id)); - - $row = $result->fetchRow(); - $folder = new OC_News_Folder($row['name'], $row['id']); - - return $folder; - } - - /** - * @brief Retrieve a feed and all its items from the database - * @param id The id of the feed in the database table. - * @returns - */ - public function findWithItems($id){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE id = ?'); - $result = $stmt->execute(array($id)); - $row = $result->fetchRow(); - $url = $row['url']; - $title = $row['title']; - $feed = new OC_News_Feed($url, $title, null,$id); - - $itemMapper = new OC_News_ItemMapper($feed); - $items = $itemMapper->findAll(); - $feed->setItems($items); - - return $feed; - } - - /** - * @brief Store the folder and all its feeds into the database - * @param folder the folder to be saved - * @returns The id of the folder in the database table. - */ - public function save(OC_News_Folder $folder){ - $query = OCP\DB::prepare(' - INSERT INTO ' . self::tableName . - '(name, parent_id, user_id) - VALUES (?, ?, ?) - '); - - $name = $folder->getName(); - - if(empty($name)) { - $l = OC_L10N::get('news'); - $name = $l->t('no name'); - } - - $parentid = $folder->getParentId(); - - $params=array( - htmlspecialchars_decode($name), - $parentid, - $this->userid - ); - $query->execute($params); - $folderid = OCP\DB::insertid(self::tableName); - - $folder->setId($folderid); - return $folderid; - } - - public function delete(OC_News_Folder $folder){ - $folderid = $folder->getId(); - return deleteById(folderid); - } - - //TODO: replace it with a DELETE INNER JOIN operation - public function deleteById($folderid){ - if ($folderid == null){ - return false; - } - - $stmt = OCP\DB::prepare('DELETE FROM ' . self::tableName .' WHERE id = ?'); - - $result = $stmt->execute(array($folderid)); - - $feedMapper = new OC_News_FeedMapper(); - //TODO: handle the value that the execute returns - $feedMapper->deleteAll($folderid); - - return true; - } - -} \ No newline at end of file diff --git a/apps/news/lib/item.php b/apps/news/lib/item.php deleted file mode 100644 index 64ae368c36..0000000000 --- a/apps/news/lib/item.php +++ /dev/null @@ -1,122 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -class StatusFlag{ - const Unread = 0x02; - const Important = 0x04; - const Deleted = 0x08; - const Updated = 0x16; -} - -/** - * This class models an item. - * - * It encapsulate a SimplePie_Item object and adds a status flag to it - */ -class OC_News_Item { - - private $url; - private $title; - private $guid; - private $body; - private $status; //a bit-field set with status flags - private $id; //id of the item in the database table - - public function __construct($url, $title, $guid, $body, $id = null){ - $this->title = $title; - $this->url = $url; - $this->guid = $guid; - $this->body = $body; - if ($id == null) { - $this->status |= StatusFlag::Unread; - } - else { - $this->id = $id; - } - } - - public function getGuid(){ - return $this->guid; - } - - public function setGuid($guid){ - $this->guid = $guid; - } - - public function getId(){ - return $this->id; - } - - public function setId($id){ - $this->id = $id; - } - - public function setRead(){ - $this->status &= ~StatusFlag::Unread; - } - - public function setUnread(){ - $this->status |= StatusFlag::Unread; - } - - public function isRead(){ - return !($this->status & StatusFlag::Unread); - } - - public function setImportant(){ - $this->status |= StatusFlag::Important; - } - - public function setUnimportant(){ - $this->status &= ~StatusFlag::Important; - } - - public function isImportant(){ - return ($this->status & StatusFlag::Important); - } - - /** - * NOTE: this is needed to store items in the database, otherwise - * the status of an item should be retrieved with methods: isRead(), isImportant(), ... - */ - public function getStatus(){ - return $this->status; - } - - public function setStatus($status){ - $this->status = $status; - } - - public function getTitle(){ - return $this->title; - } - - public function setTitle($title){ - $this->title = $title; - } - - public function getUrl(){ - return $this->url; - } - - public function setUrl($url){ - $this->url = $url; - } - - public function getBody(){ - return $this->body; - } - - public function setBody($body){ - $this->body = $body; - } -} diff --git a/apps/news/lib/itemmapper.php b/apps/news/lib/itemmapper.php deleted file mode 100644 index 8d6a755b16..0000000000 --- a/apps/news/lib/itemmapper.php +++ /dev/null @@ -1,171 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -/** - * This class maps an item to a row of the items table in the database. - * It follows the Data Mapper pattern (see http://martinfowler.com/eaaCatalog/dataMapper.html). - */ -class OC_News_ItemMapper { - - const tableName = '*PREFIX*news_items'; - - public function fromRow($row){ - $url = $row['url']; - $title = $row['title']; - $guid = $row['guid']; - $status = $row['status']; - $body = $row['body']; - $id = $row['id']; - $item = new OC_News_Item($url, $title, $guid, $body, $id); - $item->setStatus($status); - - return $item; - } - - /** - * @brief Retrieve all the item corresponding to a feed from the database - * @param feedid The id of the feed in the database table. - */ - public function findAll($feedid){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE feed_id = ?'); - $result = $stmt->execute(array($feedid)); - - $items = array(); - while ($row = $result->fetchRow()) { - $item = $this->fromRow($row); - $items[] = $item; - } - - return $items; - } - - public function findIdFromGuid($guid, $feedid){ - $stmt = OCP\DB::prepare(' - SELECT * FROM ' . self::tableName . ' - WHERE guid = ? - AND feed_id = ? - '); - $result = $stmt->execute(array($guid, $feedid)); - $row = $result->fetchRow(); - $id = null; - if ($row != null){ - $id = $row['id']; - } - return $id; - } - - /** - * @brief Update the item after its status has changed - * @returns The item whose status has changed. - */ - public function update(OC_News_Item $item){ - - $itemid = $item->getId(); - $status = $item->getStatus(); - - $stmt = OCP\DB::prepare(' - UPDATE ' . self::tableName . - ' SET status = ? - WHERE id = ? - '); - - $params=array( - $status, - $itemid - ); - $stmt->execute($params); - - return true; - } - - /** - * @brief Save the feed and all its items into the database - * @returns The id of the feed in the database table. - */ - public function save(OC_News_Item $item, $feedid){ - $guid = $item->getGuid(); - $status = $item->getStatus(); - - $itemid = $this->findIdFromGuid($guid, $feedid); - - if ($itemid == null){ - $title = $item->getTitle(); - $body = $item->getBody(); - - $stmt = OCP\DB::prepare(' - INSERT INTO ' . self::tableName . - '(url, title, body, guid, feed_id, status) - VALUES (?, ?, ?, ?, ?, ?) - '); - - if(empty($title)) { - $l = OC_L10N::get('news'); - $title = $l->t('no title'); - } - - if(empty($body)) { - $l = OC_L10N::get('news'); - $body = $l->t('no body'); - } - - $params=array( - htmlspecialchars_decode($item->getUrl()), - htmlspecialchars_decode($title), - $body, - $guid, - $feedid, - $status - ); - - $stmt->execute($params); - - $itemid = OCP\DB::insertid(self::tableName); - } - else { - $this->update($item); - } - $item->setId($itemid); - return $itemid; - } - - /** - * @brief Retrieve an item from the database - * @param id The id of the feed in the database table. - */ - public function find($id){ - $stmt = OCP\DB::prepare('SELECT * FROM ' . self::tableName . ' WHERE id = ?'); - $result = $stmt->execute(array($id)); - $row = $result->fetchRow(); - - $item = $this->fromRow($row); - - return $item; - - } - - - /** - * @brief Permanently delete all items belonging to a feed from the database - * @param feedid The id of the feed that we wish to delete - * @return - */ - public function deleteAll($feedid){ - if ($feedid == null) { - return false; - } - $stmt = OCP\DB::prepare('DELETE FROM ' . self::tableName .' WHERE feed_id = ?'); - - $result = $stmt->execute(array($feedid)); - - return $result; - } -} \ No newline at end of file diff --git a/apps/news/lib/utils.php b/apps/news/lib/utils.php deleted file mode 100644 index e18ce2969e..0000000000 --- a/apps/news/lib/utils.php +++ /dev/null @@ -1,46 +0,0 @@ - -* -* This file is licensed under the Affero General Public License version 3 or later. -* See the COPYING-README file -* -*/ - -// load SimplePie library -//TODO: is this file a suitable place for the following require? -require_once('news/3rdparty/SimplePie/SimplePieAutoloader.php'); - -class OC_News_Utils { - - /** - * @brief Fetch a feed from remote - * @param url remote url of the feed - * @returns - */ - public static function fetch($url){ - //TODO: handle the case where fetching of the feed fails - $spfeed = new SimplePie_Core(); - $spfeed->set_feed_url( $url ); - $spfeed->enable_cache( false ); - $spfeed->init(); - $spfeed->handle_content_type(); - $title = $spfeed->get_title(); - - $spitems = $spfeed->get_items(); - $items = array(); - foreach($spitems as $spitem) { //FIXME: maybe we can avoid this loop - $itemUrl = $spitem->get_permalink(); - $itemTitle = $spitem->get_title(); - $itemGUID = $spitem->get_id(); - $itemBody = $spitem->get_content(); - $items[] = new OC_News_Item($itemUrl, $itemTitle, $itemGUID, $itemBody); - } - - $feed = new OC_News_Feed($url, $title, $items); - return $feed; - } -} \ No newline at end of file diff --git a/apps/news/settings.php b/apps/news/settings.php deleted file mode 100644 index 94d0573589..0000000000 --- a/apps/news/settings.php +++ /dev/null @@ -1,8 +0,0 @@ -fetchPage(); - diff --git a/apps/news/templates/main.php b/apps/news/templates/main.php deleted file mode 100644 index 6ab1bc64ea..0000000000 --- a/apps/news/templates/main.php +++ /dev/null @@ -1,36 +0,0 @@ -
      -
        - inc("part.feeds"); ?> -
      -
      - - - -
      -
        -
      • - -
      • -
      • -
      • -
          -
      - -
      - inc("part.items"); - } - else { - echo $this->inc("part.nofeeds"); - } - ?> -
      - - -
      - - diff --git a/apps/news/templates/part.addfeed.php b/apps/news/templates/part.addfeed.php deleted file mode 100644 index 6807f3c5b3..0000000000 --- a/apps/news/templates/part.addfeed.php +++ /dev/null @@ -1,22 +0,0 @@ - -
      "> - - - - - - - - - -
      Add new feed -
      - - - -
      -
      \ No newline at end of file diff --git a/apps/news/templates/part.addfolder.php b/apps/news/templates/part.addfolder.php deleted file mode 100644 index e1217160ce..0000000000 --- a/apps/news/templates/part.addfolder.php +++ /dev/null @@ -1,22 +0,0 @@ - -
      "> - - - - - - - - - -
      Add new folder -
      - - - -
      -
      \ No newline at end of file diff --git a/apps/news/templates/part.feeds.php b/apps/news/templates/part.feeds.php deleted file mode 100644 index 587e73f366..0000000000 --- a/apps/news/templates/part.feeds.php +++ /dev/null @@ -1,31 +0,0 @@ -
    • ' . - '
      ' . strtoupper($folder->getName()) . - ( ($depth != 0) ? '' . - '': '' ) . - '
      '; - echo '
        '; - $children = $folder->getChildren(); - foreach($children as $child) { - if ($child instanceOf OC_News_Folder){ - print_folder($child, $depth+1); - } - elseif ($child instanceOf OC_News_Feed) { //onhover $(element).attr('id', 'newID'); - - echo '
      • ' . $child->getTitle() .''; - echo ''; - echo ''; - echo '
      • '; - } - else { - //TODO:handle error in this case - } - } - echo '
    • '; - } - - print_folder($_['allfeeds'], 0); -?> \ No newline at end of file diff --git a/apps/news/templates/part.folderlist.php b/apps/news/templates/part.folderlist.php deleted file mode 100644 index 670684fd4c..0000000000 --- a/apps/news/templates/part.folderlist.php +++ /dev/null @@ -1,12 +0,0 @@ -getId() . ')">' . strtoupper($folder->getName()) . ''; - $children = $folder->getChildren(); - foreach($children as $child) { - if ($child instanceOf OC_News_Folder){ - print_folder($child, $depth+1); - } - } - } - print_folder($_['allfeeds'], 0); -?> \ No newline at end of file diff --git a/apps/news/templates/part.items.php b/apps/news/templates/part.items.php deleted file mode 100644 index 24ca958e98..0000000000 --- a/apps/news/templates/part.items.php +++ /dev/null @@ -1,23 +0,0 @@ -findAll($feedid); - -echo '
        '; -foreach($items as $item) { - $title = $item->getTitle(); - echo '
      • '; - echo '
        isRead()) { - echo ' class="title_read">'; - } - else { - echo ' class="title_unread" onClick="News.Feed.markItem(' . $item->getId() . ')">'; - } - echo $title . '
        ' . $item->getBody() . '
        '; - echo '
      • '; -} -echo '
      '; diff --git a/apps/news/templates/part.nofeeds.php b/apps/news/templates/part.nofeeds.php deleted file mode 100644 index bb78dedbf8..0000000000 --- a/apps/news/templates/part.nofeeds.php +++ /dev/null @@ -1,3 +0,0 @@ -
      - t('You have no feeds in your reader.') ?> -
      \ No newline at end of file diff --git a/apps/news/templates/settings.php b/apps/news/templates/settings.php deleted file mode 100644 index ccbb004f00..0000000000 --- a/apps/news/templates/settings.php +++ /dev/null @@ -1,8 +0,0 @@ -
      -
      - News
      - -
      - -
      -
      diff --git a/apps/news/templates/test.php b/apps/news/templates/test.php deleted file mode 100644 index d8e31e6759..0000000000 --- a/apps/news/templates/test.php +++ /dev/null @@ -1,85 +0,0 @@ -save($folder); - -$feed = OC_News_Utils::fetch( 'http://www.dabacon.org/newpontiff/?feed=rss2' ); - -$feedmapper->save($feed, $folder->getId()); - -$feed = $feedmapper->findWithItems($feed->getId()); -echo '
      ' . $feed->getTitle() . '
      '; -$items = $feed->getItems(); - -foreach($items as $item) { - - echo $item->getTitle() . ' - '; - if ($item->isRead()) { - echo $l->t('Read'); - } - else { - echo $l->t('Unread'); - } - echo ' - '; - if ($item->isImportant()) { - echo $l->t('Important'); - } - else { - echo $l->t('Not important'); - } - echo '
      '; - $item->setImportant(); -} - -echo '
      ...after changing status'; -echo '
      ' . $feed->getTitle() . '
      '; - -foreach($items as $item) { - echo $item->getTitle() . ' - '; - if ($item->isRead()) { - echo $l->t('Read'); - } - else { - echo $l->t('Unread'); - } - echo ' - '; - if ($item->isImportant()) { - echo $l->t('Important'); - } - else { - echo $l->t('Not important'); - } - echo '
      '; - $item->setUnimportant(); -} - -$feedmapper->save($feed, $folder->getId()); - -echo '
      ...after saving and reloading'; - -$feed = $feedmapper->findWithItems($feed->getId()); -echo '
      ' . $feed->getTitle() . '
      '; -$items = $feed->getItems(); - -foreach($items as &$item) { - - echo $item->getTitle() . ' - '; - if ($item->isRead()) { - echo $l->t('Read'); - } - else { - echo $l->t('Unread'); - } - echo ' - '; - if ($item->isImportant()) { - echo $l->t('Important'); - } - else { - echo $l->t('Not important'); - } - echo '
      '; -} \ No newline at end of file diff --git a/apps/shorty/.htaccess b/apps/shorty/.htaccess deleted file mode 100644 index b7c4189ae4..0000000000 --- a/apps/shorty/.htaccess +++ /dev/null @@ -1,45 +0,0 @@ -# -# @package shorty an ownCloud url shortener plugin -# @category internet -# @author Christian Reiner -# @copyright 2011-2012 Christian Reiner -# @license GNU Affero General Public license (AGPL) -# @link information -# @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -# License as published by the Free Software Foundation; either -# version 3 of the license, or any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU AFFERO GENERAL PUBLIC LICENSE for more details. -# -# You should have received a copy of the GNU Affero General Public -# License along with this library. -# If not, see . -# - -# @file .htaccess -# These rules try to detect any requests that carry a "shorty id" and map them to forward.php? -# That way you can use shorter (or more simple) urls to publish or relay links -# @author Christian Reiner - -RewriteEngine On - -# example: http://.../apps/shorty/index.php/0123456789 -RewriteRule index\.php/([a-z0-9]{4,12})$ ../../public.php?service=shorty_relay&id=$1 [NC,L] - -# example: http://.../apps/shorty/index.php?0123456789 -RewriteCond %{QUERY_STRING} ^([a-z0-9]{4,12})$ [NC] -RewriteRule index\.php ../../public.php?service=shorty_relay&id=%{QUERY_STRING} [L] - -# example: http://.../apps/shorty/?0123456789 -RewriteCond %{QUERY_STRING} ^([a-z0-9]{4,12})$ [NC] -RewriteCond %{REQUEST_URI} meta/.+\.php -RewriteRule - ../../public.php?service=shorty_relay&id=%{QUERY_STRING} [L] - -# example: http://.../apps/shorty/0123456789 -RewriteRule ^([a-z0-9]{4,12})$ ../../public.php?service=shorty_relay&id=$1 [NC,L] diff --git a/apps/shorty/3rdparty/js/jquery.tinysort.min.js b/apps/shorty/3rdparty/js/jquery.tinysort.min.js deleted file mode 100644 index 225f799ca9..0000000000 --- a/apps/shorty/3rdparty/js/jquery.tinysort.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(b){var o=!1,d=null,u=parseFloat,j=String.fromCharCode,q=Math.min,l=/(\d+\.?\d*)$/g,g,a=[],h,m,t=9472,f={},c;for(var p=32,k=j(p),r=255;p96&&ab<123;if(!I){if(x=="["){var D=S.length,M=D?S[D-1]:X,w=g.substr(ad+1).match(/[^\]]*/)[0],R=w.match(/{[^}]*}/g);if(R){for(ac=0,Z=R.length;acak?1:0));if(!au&&T.charOrder){if(m){for(var ax in f){var al=f[ax];am=am.replace(ax,al);ak=ak.replace(ax,al)}}if(am.match(c)!==d||ak.match(c)!==d){for(var ap=0,ao=q(am.length,ak.length);api?1:0))){break}}}}return ai}}Q.each(function(ak,al){var am=b(al),ai=W?(J?C.filter(al):am.find(V)):am,an=ah?ai.data(T.data):(H?ai.attr(T.attr):(T.useVal?ai.val():ai.text())),aj=am.parent();if(!ae[aj]){ae[aj]={s:[],n:[]}}if(ai.length>0){ae[aj].s.push({s:an,e:am,n:ak})}else{ae[aj].n.push({e:am,n:ak})}});for(v in ae){ae[v].s.sort(F)}for(v in ae){var ag=ae[v],K=[],Y=z,af=[0,0],ad;switch(T.place){case"first":b.each(ag.s,function(ai,aj){Y=q(Y,aj.n)});break;case"org":b.each(ag.s,function(ai,aj){K.push(aj.n)});break;case"end":Y=ag.n.length;break;default:Y=0}for(ad=0;ad=Y&&ad - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - - -/* - * Version: 1.1.4 - * Build: 2010100721 - */ - - - -//---- qrconst.php ----------------------------- - - - - - -/* - * PHP QR Code encoder - * - * Common constants - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - // Encoding modes - - define('QR_MODE_NUL', -1); - define('QR_MODE_NUM', 0); - define('QR_MODE_AN', 1); - define('QR_MODE_8', 2); - define('QR_MODE_KANJI', 3); - define('QR_MODE_STRUCTURE', 4); - - // Levels of error correction. - - define('QR_ECLEVEL_L', 0); - define('QR_ECLEVEL_M', 1); - define('QR_ECLEVEL_Q', 2); - define('QR_ECLEVEL_H', 3); - - // Supported output formats - - define('QR_FORMAT_TEXT', 0); - define('QR_FORMAT_PNG', 1); - - class qrstr { - public static function set(&$srctab, $x, $y, $repl, $replLen = false) { - $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl)); - } - } - - - -//---- merged_config.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Config file, tuned-up for merged verion - */ - - define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there - define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true - define('QR_LOG_DIR', false); // default error logs dir - - define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code - define('QR_FIND_FROM_RANDOM', 2); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly - define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false - - define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images - - - - -//---- qrtools.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Toolset, handy and debug utilites. - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRtools { - - //---------------------------------------------------------------------- - public static function binarize($frame) - { - $len = count($frame); - foreach ($frame as &$frameLine) { - - for($i=0; $i<$len; $i++) { - $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0'; - } - } - - return $frame; - } - - //---------------------------------------------------------------------- - public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037') - { - $barcode_array = array(); - - if (!is_array($mode)) - $mode = explode(',', $mode); - - $eccLevel = 'L'; - - if (count($mode) > 1) { - $eccLevel = $mode[1]; - } - - $qrTab = QRcode::text($code, false, $eccLevel); - $size = count($qrTab); - - $barcode_array['num_rows'] = $size; - $barcode_array['num_cols'] = $size; - $barcode_array['bcode'] = array(); - - foreach ($qrTab as $line) { - $arrAdd = array(); - foreach(str_split($line) as $char) - $arrAdd[] = ($char=='1')?1:0; - $barcode_array['bcode'][] = $arrAdd; - } - - return $barcode_array; - } - - //---------------------------------------------------------------------- - public static function clearCache() - { - self::$frames = array(); - } - - //---------------------------------------------------------------------- - public static function buildCache() - { - QRtools::markTime('before_build_cache'); - - $mask = new QRmask(); - for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) { - $frame = QRspec::newFrame($a); - if (QR_IMAGE) { - $fileName = QR_CACHE_DIR.'frame_'.$a.'.png'; - QRimage::png(self::binarize($frame), $fileName, 1, 0); - } - - $width = count($frame); - $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); - for ($maskNo=0; $maskNo<8; $maskNo++) - $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); - } - - QRtools::markTime('after_build_cache'); - } - - //---------------------------------------------------------------------- - public static function log($outfile, $err) - { - if (QR_LOG_DIR !== false) { - if ($err != '') { - if ($outfile !== false) { - file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); - } else { - file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND); - } - } - } - } - - //---------------------------------------------------------------------- - public static function dumpMask($frame) - { - $width = count($frame); - for($y=0;$y<$width;$y++) { - for($x=0;$x<$width;$x++) { - echo ord($frame[$y][$x]).','; - } - } - } - - //---------------------------------------------------------------------- - public static function markTime($markerId) - { - list($usec, $sec) = explode(" ", microtime()); - $time = ((float)$usec + (float)$sec); - - if (!isset($GLOBALS['qr_time_bench'])) - $GLOBALS['qr_time_bench'] = array(); - - $GLOBALS['qr_time_bench'][$markerId] = $time; - } - - //---------------------------------------------------------------------- - public static function timeBenchmark() - { - self::markTime('finish'); - - $lastTime = 0; - $startTime = 0; - $p = 0; - - echo ' - - '; - - foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) { - if ($p > 0) { - echo ''; - } else { - $startTime = $thisTime; - } - - $p++; - $lastTime = $thisTime; - } - - echo ' - - -
      BENCHMARK
      till '.$markerId.': '.number_format($thisTime-$lastTime, 6).'s
      TOTAL: '.number_format($lastTime-$startTime, 6).'s
      '; - } - - } - - //########################################################################## - - QRtools::markTime('start'); - - - - -//---- qrspec.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * QR Code specifications - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * The following data / specifications are taken from - * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) - * or - * "Automatic identification and data capture techniques -- - * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('QRSPEC_VERSION_MAX', 40); - define('QRSPEC_WIDTH_MAX', 177); - - define('QRCAP_WIDTH', 0); - define('QRCAP_WORDS', 1); - define('QRCAP_REMINDER', 2); - define('QRCAP_EC', 3); - - class QRspec { - - public static $capacity = array( - array( 0, 0, 0, array( 0, 0, 0, 0)), - array( 21, 26, 0, array( 7, 10, 13, 17)), // 1 - array( 25, 44, 7, array( 10, 16, 22, 28)), - array( 29, 70, 7, array( 15, 26, 36, 44)), - array( 33, 100, 7, array( 20, 36, 52, 64)), - array( 37, 134, 7, array( 26, 48, 72, 88)), // 5 - array( 41, 172, 7, array( 36, 64, 96, 112)), - array( 45, 196, 0, array( 40, 72, 108, 130)), - array( 49, 242, 0, array( 48, 88, 132, 156)), - array( 53, 292, 0, array( 60, 110, 160, 192)), - array( 57, 346, 0, array( 72, 130, 192, 224)), //10 - array( 61, 404, 0, array( 80, 150, 224, 264)), - array( 65, 466, 0, array( 96, 176, 260, 308)), - array( 69, 532, 0, array( 104, 198, 288, 352)), - array( 73, 581, 3, array( 120, 216, 320, 384)), - array( 77, 655, 3, array( 132, 240, 360, 432)), //15 - array( 81, 733, 3, array( 144, 280, 408, 480)), - array( 85, 815, 3, array( 168, 308, 448, 532)), - array( 89, 901, 3, array( 180, 338, 504, 588)), - array( 93, 991, 3, array( 196, 364, 546, 650)), - array( 97, 1085, 3, array( 224, 416, 600, 700)), //20 - array(101, 1156, 4, array( 224, 442, 644, 750)), - array(105, 1258, 4, array( 252, 476, 690, 816)), - array(109, 1364, 4, array( 270, 504, 750, 900)), - array(113, 1474, 4, array( 300, 560, 810, 960)), - array(117, 1588, 4, array( 312, 588, 870, 1050)), //25 - array(121, 1706, 4, array( 336, 644, 952, 1110)), - array(125, 1828, 4, array( 360, 700, 1020, 1200)), - array(129, 1921, 3, array( 390, 728, 1050, 1260)), - array(133, 2051, 3, array( 420, 784, 1140, 1350)), - array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30 - array(141, 2323, 3, array( 480, 868, 1290, 1530)), - array(145, 2465, 3, array( 510, 924, 1350, 1620)), - array(149, 2611, 3, array( 540, 980, 1440, 1710)), - array(153, 2761, 3, array( 570, 1036, 1530, 1800)), - array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35 - array(161, 3034, 0, array( 600, 1120, 1680, 1980)), - array(165, 3196, 0, array( 630, 1204, 1770, 2100)), - array(169, 3362, 0, array( 660, 1260, 1860, 2220)), - array(173, 3532, 0, array( 720, 1316, 1950, 2310)), - array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40 - ); - - //---------------------------------------------------------------------- - public static function getDataLength($version, $level) - { - return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level]; - } - - //---------------------------------------------------------------------- - public static function getECCLength($version, $level) - { - return self::$capacity[$version][QRCAP_EC][$level]; - } - - //---------------------------------------------------------------------- - public static function getWidth($version) - { - return self::$capacity[$version][QRCAP_WIDTH]; - } - - //---------------------------------------------------------------------- - public static function getRemainder($version) - { - return self::$capacity[$version][QRCAP_REMINDER]; - } - - //---------------------------------------------------------------------- - public static function getMinimumVersion($size, $level) - { - - for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) { - $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level]; - if($words >= $size) - return $i; - } - - return -1; - } - - //###################################################################### - - public static $lengthTableBits = array( - array(10, 12, 14), - array( 9, 11, 13), - array( 8, 16, 16), - array( 8, 10, 12) - ); - - //---------------------------------------------------------------------- - public static function lengthIndicator($mode, $version) - { - if ($mode == QR_MODE_STRUCTURE) - return 0; - - if ($version <= 9) { - $l = 0; - } else if ($version <= 26) { - $l = 1; - } else { - $l = 2; - } - - return self::$lengthTableBits[$mode][$l]; - } - - //---------------------------------------------------------------------- - public static function maximumWords($mode, $version) - { - if($mode == QR_MODE_STRUCTURE) - return 3; - - if($version <= 9) { - $l = 0; - } else if($version <= 26) { - $l = 1; - } else { - $l = 2; - } - - $bits = self::$lengthTableBits[$mode][$l]; - $words = (1 << $bits) - 1; - - if($mode == QR_MODE_KANJI) { - $words *= 2; // the number of bytes is required - } - - return $words; - } - - // Error correction code ----------------------------------------------- - // Table of the error correction code (Reed-Solomon block) - // See Table 12-16 (pp.30-36), JIS X0510:2004. - - public static $eccTable = array( - array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)), - array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1 - array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), - array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)), - array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)), - array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5 - array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)), - array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)), - array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)), - array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)), - array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10 - array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)), - array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)), - array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)), - array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)), - array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15 - array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)), - array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)), - array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)), - array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)), - array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20 - array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)), - array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)), - array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)), - array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)), - array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25 - array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)), - array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)), - array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)), - array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)), - array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30 - array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)), - array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)), - array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)), - array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)), - array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35 - array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)), - array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)), - array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)), - array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)), - array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40 - ); - - //---------------------------------------------------------------------- - // CACHEABLE!!! - - public static function getEccSpec($version, $level, array &$spec) - { - if (count($spec) < 5) { - $spec = array(0,0,0,0,0); - } - - $b1 = self::$eccTable[$version][$level][0]; - $b2 = self::$eccTable[$version][$level][1]; - $data = self::getDataLength($version, $level); - $ecc = self::getECCLength($version, $level); - - if($b2 == 0) { - $spec[0] = $b1; - $spec[1] = (int)($data / $b1); - $spec[2] = (int)($ecc / $b1); - $spec[3] = 0; - $spec[4] = 0; - } else { - $spec[0] = $b1; - $spec[1] = (int)($data / ($b1 + $b2)); - $spec[2] = (int)($ecc / ($b1 + $b2)); - $spec[3] = $b2; - $spec[4] = $spec[1] + 1; - } - } - - // Alignment pattern --------------------------------------------------- - - // Positions of alignment patterns. - // This array includes only the second and the third position of the - // alignment patterns. Rest of them can be calculated from the distance - // between them. - - // See Table 1 in Appendix E (pp.71) of JIS X0510:2004. - - public static $alignmentPattern = array( - array( 0, 0), - array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5 - array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10 - array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15 - array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20 - array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25 - array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30 - array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35 - array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40 - ); - - - /** -------------------------------------------------------------------- - * Put an alignment marker. - * @param frame - * @param width - * @param ox,oy center coordinate of the pattern - */ - public static function putAlignmentMarker(array &$frame, $ox, $oy) - { - $finder = array( - "\xa1\xa1\xa1\xa1\xa1", - "\xa1\xa0\xa0\xa0\xa1", - "\xa1\xa0\xa1\xa0\xa1", - "\xa1\xa0\xa0\xa0\xa1", - "\xa1\xa1\xa1\xa1\xa1" - ); - - $yStart = $oy-2; - $xStart = $ox-2; - - for($y=0; $y<5; $y++) { - QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]); - } - } - - //---------------------------------------------------------------------- - public static function putAlignmentPattern($version, &$frame, $width) - { - if($version < 2) - return; - - $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0]; - if($d < 0) { - $w = 2; - } else { - $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2); - } - - if($w * $w - 3 == 1) { - $x = self::$alignmentPattern[$version][0]; - $y = self::$alignmentPattern[$version][0]; - self::putAlignmentMarker($frame, $x, $y); - return; - } - - $cx = self::$alignmentPattern[$version][0]; - for($x=1; $x<$w - 1; $x++) { - self::putAlignmentMarker($frame, 6, $cx); - self::putAlignmentMarker($frame, $cx, 6); - $cx += $d; - } - - $cy = self::$alignmentPattern[$version][0]; - for($y=0; $y<$w-1; $y++) { - $cx = self::$alignmentPattern[$version][0]; - for($x=0; $x<$w-1; $x++) { - self::putAlignmentMarker($frame, $cx, $cy); - $cx += $d; - } - $cy += $d; - } - } - - // Version information pattern ----------------------------------------- - - // Version information pattern (BCH coded). - // See Table 1 in Appendix D (pp.68) of JIS X0510:2004. - - // size: [QRSPEC_VERSION_MAX - 6] - - public static $versionPattern = array( - 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d, - 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9, - 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75, - 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64, - 0x27541, 0x28c69 - ); - - //---------------------------------------------------------------------- - public static function getVersionPattern($version) - { - if($version < 7 || $version > QRSPEC_VERSION_MAX) - return 0; - - return self::$versionPattern[$version -7]; - } - - // Format information -------------------------------------------------- - // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib) - - public static $formatInfo = array( - array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976), - array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0), - array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed), - array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b) - ); - - public static function getFormatInfo($mask, $level) - { - if($mask < 0 || $mask > 7) - return 0; - - if($level < 0 || $level > 3) - return 0; - - return self::$formatInfo[$level][$mask]; - } - - // Frame --------------------------------------------------------------- - // Cache of initial frames. - - public static $frames = array(); - - /** -------------------------------------------------------------------- - * Put a finder pattern. - * @param frame - * @param width - * @param ox,oy upper-left coordinate of the pattern - */ - public static function putFinderPattern(&$frame, $ox, $oy) - { - $finder = array( - "\xc1\xc1\xc1\xc1\xc1\xc1\xc1", - "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", - "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", - "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", - "\xc1\xc0\xc1\xc1\xc1\xc0\xc1", - "\xc1\xc0\xc0\xc0\xc0\xc0\xc1", - "\xc1\xc1\xc1\xc1\xc1\xc1\xc1" - ); - - for($y=0; $y<7; $y++) { - QRstr::set($frame, $ox, $oy+$y, $finder[$y]); - } - } - - //---------------------------------------------------------------------- - public static function createFrame($version) - { - $width = self::$capacity[$version][QRCAP_WIDTH]; - $frameLine = str_repeat ("\0", $width); - $frame = array_fill(0, $width, $frameLine); - - // Finder pattern - self::putFinderPattern($frame, 0, 0); - self::putFinderPattern($frame, $width - 7, 0); - self::putFinderPattern($frame, 0, $width - 7); - - // Separator - $yOffset = $width - 7; - - for($y=0; $y<7; $y++) { - $frame[$y][7] = "\xc0"; - $frame[$y][$width - 8] = "\xc0"; - $frame[$yOffset][7] = "\xc0"; - $yOffset++; - } - - $setPattern = str_repeat("\xc0", 8); - - QRstr::set($frame, 0, 7, $setPattern); - QRstr::set($frame, $width-8, 7, $setPattern); - QRstr::set($frame, 0, $width - 8, $setPattern); - - // Format info - $setPattern = str_repeat("\x84", 9); - QRstr::set($frame, 0, 8, $setPattern); - QRstr::set($frame, $width - 8, 8, $setPattern, 8); - - $yOffset = $width - 8; - - for($y=0; $y<8; $y++,$yOffset++) { - $frame[$y][8] = "\x84"; - $frame[$yOffset][8] = "\x84"; - } - - // Timing pattern - - for($i=1; $i<$width-15; $i++) { - $frame[6][7+$i] = chr(0x90 | ($i & 1)); - $frame[7+$i][6] = chr(0x90 | ($i & 1)); - } - - // Alignment pattern - self::putAlignmentPattern($version, $frame, $width); - - // Version information - if($version >= 7) { - $vinf = self::getVersionPattern($version); - - $v = $vinf; - - for($x=0; $x<6; $x++) { - for($y=0; $y<3; $y++) { - $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1)); - $v = $v >> 1; - } - } - - $v = $vinf; - for($y=0; $y<6; $y++) { - for($x=0; $x<3; $x++) { - $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1)); - $v = $v >> 1; - } - } - } - - // and a little bit... - $frame[$width - 8][8] = "\x81"; - - return $frame; - } - - //---------------------------------------------------------------------- - public static function debug($frame, $binary_mode = false) - { - if ($binary_mode) { - - foreach ($frame as &$frameLine) { - $frameLine = join('  ', explode('0', $frameLine)); - $frameLine = join('██', explode('1', $frameLine)); - } - - ?> - -


              '; - echo join("
              ", $frame); - echo '






      '; - - } else { - - foreach ($frame as &$frameLine) { - $frameLine = join(' ', explode("\xc0", $frameLine)); - $frameLine = join('', explode("\xc1", $frameLine)); - $frameLine = join(' ', explode("\xa0", $frameLine)); - $frameLine = join('', explode("\xa1", $frameLine)); - $frameLine = join('', explode("\x84", $frameLine)); //format 0 - $frameLine = join('', explode("\x85", $frameLine)); //format 1 - $frameLine = join('', explode("\x81", $frameLine)); //special bit - $frameLine = join(' ', explode("\x90", $frameLine)); //clock 0 - $frameLine = join('', explode("\x91", $frameLine)); //clock 1 - $frameLine = join(' ', explode("\x88", $frameLine)); //version - $frameLine = join('', explode("\x89", $frameLine)); //version - $frameLine = join('♦', explode("\x01", $frameLine)); - $frameLine = join('⋅', explode("\0", $frameLine)); - } - - ?> - - "; - echo join("
      ", $frame); - echo "
      "; - - } - } - - //---------------------------------------------------------------------- - public static function serial($frame) - { - return gzcompress(join("\n", $frame), 9); - } - - //---------------------------------------------------------------------- - public static function unserial($code) - { - return explode("\n", gzuncompress($code)); - } - - //---------------------------------------------------------------------- - public static function newFrame($version) - { - if($version < 1 || $version > QRSPEC_VERSION_MAX) - return null; - - if(!isset(self::$frames[$version])) { - - $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat'; - - if (QR_CACHEABLE) { - if (file_exists($fileName)) { - self::$frames[$version] = self::unserial(file_get_contents($fileName)); - } else { - self::$frames[$version] = self::createFrame($version); - file_put_contents($fileName, self::serial(self::$frames[$version])); - } - } else { - self::$frames[$version] = self::createFrame($version); - } - } - - if(is_null(self::$frames[$version])) - return null; - - return self::$frames[$version]; - } - - //---------------------------------------------------------------------- - public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; } - public static function rsBlockNum1($spec) { return $spec[0]; } - public static function rsDataCodes1($spec) { return $spec[1]; } - public static function rsEccCodes1($spec) { return $spec[2]; } - public static function rsBlockNum2($spec) { return $spec[3]; } - public static function rsDataCodes2($spec) { return $spec[4]; } - public static function rsEccCodes2($spec) { return $spec[2]; } - public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); } - public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; } - - } - - - -//---- qrimage.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Image output of code using GD2 - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('QR_IMAGE', true); - - class QRimage { - - //---------------------------------------------------------------------- - public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE) - { - $image = self::image($frame, $pixelPerPoint, $outerFrame); - - if ($filename === false) { - Header("Content-type: image/png"); - ImagePng($image); - } else { - if($saveandprint===TRUE){ - ImagePng($image, $filename); - header("Content-type: image/png"); - ImagePng($image); - }else{ - ImagePng($image, $filename); - } - } - - ImageDestroy($image); - } - - //---------------------------------------------------------------------- - public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) - { - $image = self::image($frame, $pixelPerPoint, $outerFrame); - - if ($filename === false) { - Header("Content-type: image/jpeg"); - ImageJpeg($image, null, $q); - } else { - ImageJpeg($image, $filename, $q); - } - - ImageDestroy($image); - } - - //---------------------------------------------------------------------- - private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) - { - $h = count($frame); - $w = strlen($frame[0]); - - $imgW = $w + 2*$outerFrame; - $imgH = $h + 2*$outerFrame; - - $base_image =ImageCreate($imgW, $imgH); - - $col[0] = ImageColorAllocate($base_image,255,255,255); - $col[1] = ImageColorAllocate($base_image,0,0,0); - - imagefill($base_image, 0, 0, $col[0]); - - for($y=0; $y<$h; $y++) { - for($x=0; $x<$w; $x++) { - if ($frame[$y][$x] == '1') { - ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]); - } - } - } - - $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint); - ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH); - ImageDestroy($base_image); - - return $target_image; - } - } - - - -//---- qrinput.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Input encoding class - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('STRUCTURE_HEADER_BITS', 20); - define('MAX_STRUCTURED_SYMBOLS', 16); - - class QRinputItem { - - public $mode; - public $size; - public $data; - public $bstream; - - public function __construct($mode, $size, $data, $bstream = null) - { - $setData = array_slice($data, 0, $size); - - if (count($setData) < $size) { - $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); - } - - if(!QRinput::check($mode, $size, $setData)) { - throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); - return null; - } - - $this->mode = $mode; - $this->size = $size; - $this->data = $setData; - $this->bstream = $bstream; - } - - //---------------------------------------------------------------------- - public function encodeModeNum($version) - { - try { - - $words = (int)($this->size / 3); - $bs = new QRbitstream(); - - $val = 0x1; - $bs->appendNum(4, $val); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size); - - for($i=0; $i<$words; $i++) { - $val = (ord($this->data[$i*3 ]) - ord('0')) * 100; - $val += (ord($this->data[$i*3+1]) - ord('0')) * 10; - $val += (ord($this->data[$i*3+2]) - ord('0')); - $bs->appendNum(10, $val); - } - - if($this->size - $words * 3 == 1) { - $val = ord($this->data[$words*3]) - ord('0'); - $bs->appendNum(4, $val); - } else if($this->size - $words * 3 == 2) { - $val = (ord($this->data[$words*3 ]) - ord('0')) * 10; - $val += (ord($this->data[$words*3+1]) - ord('0')); - $bs->appendNum(7, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeAn($version) - { - try { - $words = (int)($this->size / 2); - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x02); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size); - - for($i=0; $i<$words; $i++) { - $val = (int)QRinput::lookAnTable(ord($this->data[$i*2 ])) * 45; - $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1])); - - $bs->appendNum(11, $val); - } - - if($this->size & 1) { - $val = QRinput::lookAnTable(ord($this->data[$words * 2])); - $bs->appendNum(6, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeMode8($version) - { - try { - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x4); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size); - - for($i=0; $i<$this->size; $i++) { - $bs->appendNum(8, ord($this->data[$i])); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeKanji($version) - { - try { - - $bs = new QRbitrtream(); - - $bs->appendNum(4, 0x8); - $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2)); - - for($i=0; $i<$this->size; $i+=2) { - $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]); - if($val <= 0x9ffc) { - $val -= 0x8140; - } else { - $val -= 0xc140; - } - - $h = ($val >> 8) * 0xc0; - $val = ($val & 0xff) + $h; - - $bs->appendNum(13, $val); - } - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function encodeModeStructure() - { - try { - $bs = new QRbitstream(); - - $bs->appendNum(4, 0x03); - $bs->appendNum(4, ord($this->data[1]) - 1); - $bs->appendNum(4, ord($this->data[0]) - 1); - $bs->appendNum(8, ord($this->data[2])); - - $this->bstream = $bs; - return 0; - - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function estimateBitStreamSizeOfEntry($version) - { - $bits = 0; - - if($version == 0) - $version = 1; - - switch($this->mode) { - case QR_MODE_NUM: $bits = QRinput::estimateBitsModeNum($this->size); break; - case QR_MODE_AN: $bits = QRinput::estimateBitsModeAn($this->size); break; - case QR_MODE_8: $bits = QRinput::estimateBitsMode8($this->size); break; - case QR_MODE_KANJI: $bits = QRinput::estimateBitsModeKanji($this->size);break; - case QR_MODE_STRUCTURE: return STRUCTURE_HEADER_BITS; - default: - return 0; - } - - $l = QRspec::lengthIndicator($this->mode, $version); - $m = 1 << $l; - $num = (int)(($this->size + $m - 1) / $m); - - $bits += $num * (4 + $l); - - return $bits; - } - - //---------------------------------------------------------------------- - public function encodeBitStream($version) - { - try { - - unset($this->bstream); - $words = QRspec::maximumWords($this->mode, $version); - - if($this->size > $words) { - - $st1 = new QRinputItem($this->mode, $words, $this->data); - $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); - - $st1->encodeBitStream($version); - $st2->encodeBitStream($version); - - $this->bstream = new QRbitstream(); - $this->bstream->append($st1->bstream); - $this->bstream->append($st2->bstream); - - unset($st1); - unset($st2); - - } else { - - $ret = 0; - - switch($this->mode) { - case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; - case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; - case QR_MODE_8: $ret = $this->encodeMode8($version); break; - case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version);break; - case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; - - default: - break; - } - - if($ret < 0) - return -1; - } - - return $this->bstream->size(); - - } catch (Exception $e) { - return -1; - } - } - }; - - //########################################################################## - - class QRinput { - - public $items; - - private $version; - private $level; - - //---------------------------------------------------------------------- - public function __construct($version = 0, $level = QR_ECLEVEL_L) - { - if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) { - throw new Exception('Invalid version no'); - return NULL; - } - - $this->version = $version; - $this->level = $level; - } - - //---------------------------------------------------------------------- - public function getVersion() - { - return $this->version; - } - - //---------------------------------------------------------------------- - public function setVersion($version) - { - if($version < 0 || $version > QRSPEC_VERSION_MAX) { - throw new Exception('Invalid version no'); - return -1; - } - - $this->version = $version; - - return 0; - } - - //---------------------------------------------------------------------- - public function getErrorCorrectionLevel() - { - return $this->level; - } - - //---------------------------------------------------------------------- - public function setErrorCorrectionLevel($level) - { - if($level > QR_ECLEVEL_H) { - throw new Exception('Invalid ECLEVEL'); - return -1; - } - - $this->level = $level; - - return 0; - } - - //---------------------------------------------------------------------- - public function appendEntry(QRinputItem $entry) - { - $this->items[] = $entry; - } - - //---------------------------------------------------------------------- - public function append($mode, $size, $data) - { - try { - $entry = new QRinputItem($mode, $size, $data); - $this->items[] = $entry; - return 0; - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - - public function insertStructuredAppendHeader($size, $index, $parity) - { - if( $size > MAX_STRUCTURED_SYMBOLS ) { - throw new Exception('insertStructuredAppendHeader wrong size'); - } - - if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) { - throw new Exception('insertStructuredAppendHeader wrong index'); - } - - $buf = array($size, $index, $parity); - - try { - $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf); - array_unshift($this->items, $entry); - return 0; - } catch (Exception $e) { - return -1; - } - } - - //---------------------------------------------------------------------- - public function calcParity() - { - $parity = 0; - - foreach($this->items as $item) { - if($item->mode != QR_MODE_STRUCTURE) { - for($i=$item->size-1; $i>=0; $i--) { - $parity ^= $item->data[$i]; - } - } - } - - return $parity; - } - - //---------------------------------------------------------------------- - public static function checkModeNum($size, $data) - { - for($i=0; $i<$size; $i++) { - if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ - return false; - } - } - - return true; - } - - //---------------------------------------------------------------------- - public static function estimateBitsModeNum($size) - { - $w = (int)$size / 3; - $bits = $w * 10; - - switch($size - $w * 3) { - case 1: - $bits += 4; - break; - case 2: - $bits += 7; - break; - default: - break; - } - - return $bits; - } - - //---------------------------------------------------------------------- - public static $anTable = array( - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - ); - - //---------------------------------------------------------------------- - public static function lookAnTable($c) - { - return (($c > 127)?-1:self::$anTable[$c]); - } - - //---------------------------------------------------------------------- - public static function checkModeAn($size, $data) - { - for($i=0; $i<$size; $i++) { - if (self::lookAnTable(ord($data[$i])) == -1) { - return false; - } - } - - return true; - } - - //---------------------------------------------------------------------- - public static function estimateBitsModeAn($size) - { - $w = (int)($size / 2); - $bits = $w * 11; - - if($size & 1) { - $bits += 6; - } - - return $bits; - } - - //---------------------------------------------------------------------- - public static function estimateBitsMode8($size) - { - return $size * 8; - } - - //---------------------------------------------------------------------- - public function estimateBitsModeKanji($size) - { - return (int)(($size / 2) * 13); - } - - //---------------------------------------------------------------------- - public static function checkModeKanji($size, $data) - { - if($size & 1) - return false; - - for($i=0; $i<$size; $i+=2) { - $val = (ord($data[$i]) << 8) | ord($data[$i+1]); - if( $val < 0x8140 - || ($val > 0x9ffc && $val < 0xe040) - || $val > 0xebbf) { - return false; - } - } - - return true; - } - - /*********************************************************************** - * Validation - **********************************************************************/ - - public static function check($mode, $size, $data) - { - if($size <= 0) - return false; - - switch($mode) { - case QR_MODE_NUM: return self::checkModeNum($size, $data); break; - case QR_MODE_AN: return self::checkModeAn($size, $data); break; - case QR_MODE_KANJI: return self::checkModeKanji($size, $data); break; - case QR_MODE_8: return true; break; - case QR_MODE_STRUCTURE: return true; break; - - default: - break; - } - - return false; - } - - - //---------------------------------------------------------------------- - public function estimateBitStreamSize($version) - { - $bits = 0; - - foreach($this->items as $item) { - $bits += $item->estimateBitStreamSizeOfEntry($version); - } - - return $bits; - } - - //---------------------------------------------------------------------- - public function estimateVersion() - { - $version = 0; - $prev = 0; - do { - $prev = $version; - $bits = $this->estimateBitStreamSize($prev); - $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); - if ($version < 0) { - return -1; - } - } while ($version > $prev); - - return $version; - } - - //---------------------------------------------------------------------- - public static function lengthOfCode($mode, $version, $bits) - { - $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version); - switch($mode) { - case QR_MODE_NUM: - $chunks = (int)($payload / 10); - $remain = $payload - $chunks * 10; - $size = $chunks * 3; - if($remain >= 7) { - $size += 2; - } else if($remain >= 4) { - $size += 1; - } - break; - case QR_MODE_AN: - $chunks = (int)($payload / 11); - $remain = $payload - $chunks * 11; - $size = $chunks * 2; - if($remain >= 6) - $size++; - break; - case QR_MODE_8: - $size = (int)($payload / 8); - break; - case QR_MODE_KANJI: - $size = (int)(($payload / 13) * 2); - break; - case QR_MODE_STRUCTURE: - $size = (int)($payload / 8); - break; - default: - $size = 0; - break; - } - - $maxsize = QRspec::maximumWords($mode, $version); - if($size < 0) $size = 0; - if($size > $maxsize) $size = $maxsize; - - return $size; - } - - //---------------------------------------------------------------------- - public function createBitStream() - { - $total = 0; - - foreach($this->items as $item) { - $bits = $item->encodeBitStream($this->version); - - if($bits < 0) - return -1; - - $total += $bits; - } - - return $total; - } - - //---------------------------------------------------------------------- - public function convertData() - { - $ver = $this->estimateVersion(); - if($ver > $this->getVersion()) { - $this->setVersion($ver); - } - - for(;;) { - $bits = $this->createBitStream(); - - if($bits < 0) - return -1; - - $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level); - if($ver < 0) { - throw new Exception('WRONG VERSION'); - return -1; - } else if($ver > $this->getVersion()) { - $this->setVersion($ver); - } else { - break; - } - } - - return 0; - } - - //---------------------------------------------------------------------- - public function appendPaddingBit(&$bstream) - { - $bits = $bstream->size(); - $maxwords = QRspec::getDataLength($this->version, $this->level); - $maxbits = $maxwords * 8; - - if ($maxbits == $bits) { - return 0; - } - - if ($maxbits - $bits < 5) { - return $bstream->appendNum($maxbits - $bits, 0); - } - - $bits += 4; - $words = (int)(($bits + 7) / 8); - - $padding = new QRbitstream(); - $ret = $padding->appendNum($words * 8 - $bits + 4, 0); - - if($ret < 0) - return $ret; - - $padlen = $maxwords - $words; - - if($padlen > 0) { - - $padbuf = array(); - for($i=0; $i<$padlen; $i++) { - $padbuf[$i] = ($i&1)?0x11:0xec; - } - - $ret = $padding->appendBytes($padlen, $padbuf); - - if($ret < 0) - return $ret; - - } - - $ret = $bstream->append($padding); - - return $ret; - } - - //---------------------------------------------------------------------- - public function mergeBitStream() - { - if($this->convertData() < 0) { - return null; - } - - $bstream = new QRbitstream(); - - foreach($this->items as $item) { - $ret = $bstream->append($item->bstream); - if($ret < 0) { - return null; - } - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function getBitStream() - { - - $bstream = $this->mergeBitStream(); - - if($bstream == null) { - return null; - } - - $ret = $this->appendPaddingBit($bstream); - if($ret < 0) { - return null; - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function getByteStream() - { - $bstream = $this->getBitStream(); - if($bstream == null) { - return null; - } - - return $bstream->toByte(); - } - } - - - - - - -//---- qrbitstream.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Bitstream class - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRbitstream { - - public $data = array(); - - //---------------------------------------------------------------------- - public function size() - { - return count($this->data); - } - - //---------------------------------------------------------------------- - public function allocate($setLength) - { - $this->data = array_fill(0, $setLength, 0); - return 0; - } - - //---------------------------------------------------------------------- - public static function newFromNum($bits, $num) - { - $bstream = new QRbitstream(); - $bstream->allocate($bits); - - $mask = 1 << ($bits - 1); - for($i=0; $i<$bits; $i++) { - if($num & $mask) { - $bstream->data[$i] = 1; - } else { - $bstream->data[$i] = 0; - } - $mask = $mask >> 1; - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public static function newFromBytes($size, $data) - { - $bstream = new QRbitstream(); - $bstream->allocate($size * 8); - $p=0; - - for($i=0; $i<$size; $i++) { - $mask = 0x80; - for($j=0; $j<8; $j++) { - if($data[$i] & $mask) { - $bstream->data[$p] = 1; - } else { - $bstream->data[$p] = 0; - } - $p++; - $mask = $mask >> 1; - } - } - - return $bstream; - } - - //---------------------------------------------------------------------- - public function append(QRbitstream $arg) - { - if (is_null($arg)) { - return -1; - } - - if($arg->size() == 0) { - return 0; - } - - if($this->size() == 0) { - $this->data = $arg->data; - return 0; - } - - $this->data = array_values(array_merge($this->data, $arg->data)); - - return 0; - } - - //---------------------------------------------------------------------- - public function appendNum($bits, $num) - { - if ($bits == 0) - return 0; - - $b = QRbitstream::newFromNum($bits, $num); - - if(is_null($b)) - return -1; - - $ret = $this->append($b); - unset($b); - - return $ret; - } - - //---------------------------------------------------------------------- - public function appendBytes($size, $data) - { - if ($size == 0) - return 0; - - $b = QRbitstream::newFromBytes($size, $data); - - if(is_null($b)) - return -1; - - $ret = $this->append($b); - unset($b); - - return $ret; - } - - //---------------------------------------------------------------------- - public function toByte() - { - - $size = $this->size(); - - if($size == 0) { - return array(); - } - - $data = array_fill(0, (int)(($size + 7) / 8), 0); - $bytes = (int)($size / 8); - - $p = 0; - - for($i=0; $i<$bytes; $i++) { - $v = 0; - for($j=0; $j<8; $j++) { - $v = $v << 1; - $v |= $this->data[$p]; - $p++; - } - $data[$i] = $v; - } - - if($size & 7) { - $v = 0; - for($j=0; $j<($size & 7); $j++) { - $v = $v << 1; - $v |= $this->data[$p]; - $p++; - } - $data[$bytes] = $v; - } - - return $data; - } - - } - - - - -//---- qrsplit.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Input splitting classes - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * The following data / specifications are taken from - * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004) - * or - * "Automatic identification and data capture techniques -- - * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - class QRsplit { - - public $dataStr = ''; - public $input; - public $modeHint; - - //---------------------------------------------------------------------- - public function __construct($dataStr, $input, $modeHint) - { - $this->dataStr = $dataStr; - $this->input = $input; - $this->modeHint = $modeHint; - } - - //---------------------------------------------------------------------- - public static function isdigitat($str, $pos) - { - if ($pos >= strlen($str)) - return false; - - return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9'))); - } - - //---------------------------------------------------------------------- - public static function isalnumat($str, $pos) - { - if ($pos >= strlen($str)) - return false; - - return (QRinput::lookAnTable(ord($str[$pos])) >= 0); - } - - //---------------------------------------------------------------------- - public function identifyMode($pos) - { - if ($pos >= strlen($this->dataStr)) - return QR_MODE_NUL; - - $c = $this->dataStr[$pos]; - - if(self::isdigitat($this->dataStr, $pos)) { - return QR_MODE_NUM; - } else if(self::isalnumat($this->dataStr, $pos)) { - return QR_MODE_AN; - } else if($this->modeHint == QR_MODE_KANJI) { - - if ($pos+1 < strlen($this->dataStr)) - { - $d = $this->dataStr[$pos+1]; - $word = (ord($c) << 8) | ord($d); - if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) { - return QR_MODE_KANJI; - } - } - } - - return QR_MODE_8; - } - - //---------------------------------------------------------------------- - public function eatNum() - { - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 0; - while(self::isdigitat($this->dataStr, $p)) { - $p++; - } - - $run = $p; - $mode = $this->identifyMode($p); - - if($mode == QR_MODE_8) { - $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln - + QRinput::estimateBitsMode8(1) // + 4 + l8 - - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 - if($dif > 0) { - return $this->eat8(); - } - } - if($mode == QR_MODE_AN) { - $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln - + QRinput::estimateBitsModeAn(1) // + 4 + la - - QRinput::estimateBitsModeAn($run + 1);// - 4 - la - if($dif > 0) { - return $this->eatAn(); - } - } - - $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eatAn() - { - $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 0; - - while(self::isalnumat($this->dataStr, $p)) { - if(self::isdigitat($this->dataStr, $p)) { - $q = $p; - while(self::isdigitat($this->dataStr, $q)) { - $q++; - } - - $dif = QRinput::estimateBitsModeAn($p) // + 4 + la - + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - - QRinput::estimateBitsModeAn($q); // - 4 - la - - if($dif < 0) { - break; - } else { - $p = $q; - } - } else { - $p++; - } - } - - $run = $p; - - if(!self::isalnumat($this->dataStr, $p)) { - $dif = QRinput::estimateBitsModeAn($run) + 4 + $la - + QRinput::estimateBitsMode8(1) // + 4 + l8 - - QRinput::estimateBitsMode8($run + 1); // - 4 - l8 - if($dif > 0) { - return $this->eat8(); - } - } - - $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eatKanji() - { - $p = 0; - - while($this->identifyMode($p) == QR_MODE_KANJI) { - $p += 2; - } - - $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr)); - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function eat8() - { - $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); - $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); - - $p = 1; - $dataStrLen = strlen($this->dataStr); - - while($p < $dataStrLen) { - - $mode = $this->identifyMode($p); - if($mode == QR_MODE_KANJI) { - break; - } - if($mode == QR_MODE_NUM) { - $q = $p; - while(self::isdigitat($this->dataStr, $q)) { - $q++; - } - $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 - + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - - QRinput::estimateBitsMode8($q); // - 4 - l8 - if($dif < 0) { - break; - } else { - $p = $q; - } - } else if($mode == QR_MODE_AN) { - $q = $p; - while(self::isalnumat($this->dataStr, $q)) { - $q++; - } - $dif = QRinput::estimateBitsMode8($p) // + 4 + l8 - + QRinput::estimateBitsModeAn($q - $p) + 4 + $la - - QRinput::estimateBitsMode8($q); // - 4 - l8 - if($dif < 0) { - break; - } else { - $p = $q; - } - } else { - $p++; - } - } - - $run = $p; - $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); - - if($ret < 0) - return -1; - - return $run; - } - - //---------------------------------------------------------------------- - public function splitString() - { - while (strlen($this->dataStr) > 0) - { - if($this->dataStr == '') - return 0; - - $mode = $this->identifyMode(0); - - switch ($mode) { - case QR_MODE_NUM: $length = $this->eatNum(); break; - case QR_MODE_AN: $length = $this->eatAn(); break; - case QR_MODE_KANJI: - if ($hint == QR_MODE_KANJI) - $length = $this->eatKanji(); - else $length = $this->eat8(); - break; - default: $length = $this->eat8(); break; - - } - - if($length == 0) return 0; - if($length < 0) return -1; - - $this->dataStr = substr($this->dataStr, $length); - } - } - - //---------------------------------------------------------------------- - public function toUpper() - { - $stringLen = strlen($this->dataStr); - $p = 0; - - while ($p<$stringLen) { - $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint); - if($mode == QR_MODE_KANJI) { - $p += 2; - } else { - if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) { - $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32); - } - $p++; - } - } - - return $this->dataStr; - } - - //---------------------------------------------------------------------- - public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true) - { - if(is_null($string) || $string == '\0' || $string == '') { - throw new Exception('empty string!!!'); - } - - $split = new QRsplit($string, $input, $modeHint); - - if(!$casesensitive) - $split->toUpper(); - - return $split->splitString(); - } - } - - - -//---- qrrscode.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Reed-Solomon error correction support - * - * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q - * (libfec is released under the GNU Lesser General Public License.) - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRrsItem { - - public $mm; // Bits per symbol - public $nn; // Symbols per block (= (1<= $this->nn) { - $x -= $this->nn; - $x = ($x >> $this->mm) + ($x & $this->nn); - } - - return $x; - } - - //---------------------------------------------------------------------- - public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) - { - // Common code for intializing a Reed-Solomon control block (char or int symbols) - // Copyright 2004 Phil Karn, KA9Q - // May be used under the terms of the GNU Lesser General Public License (LGPL) - - $rs = null; - - // Check parameter ranges - if($symsize < 0 || $symsize > 8) return $rs; - if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs; - if($prim <= 0 || $prim >= (1<<$symsize)) return $rs; - if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values! - if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding - - $rs = new QRrsItem(); - $rs->mm = $symsize; - $rs->nn = (1<<$symsize)-1; - $rs->pad = $pad; - - $rs->alpha_to = array_fill(0, $rs->nn+1, 0); - $rs->index_of = array_fill(0, $rs->nn+1, 0); - - // PHP style macro replacement ;) - $NN =& $rs->nn; - $A0 =& $NN; - - // Generate Galois field lookup tables - $rs->index_of[0] = $A0; // log(zero) = -inf - $rs->alpha_to[$A0] = 0; // alpha**-inf = 0 - $sr = 1; - - for($i=0; $i<$rs->nn; $i++) { - $rs->index_of[$sr] = $i; - $rs->alpha_to[$i] = $sr; - $sr <<= 1; - if($sr & (1<<$symsize)) { - $sr ^= $gfpoly; - } - $sr &= $rs->nn; - } - - if($sr != 1){ - // field generator polynomial is not primitive! - $rs = NULL; - return $rs; - } - - /* Form RS code generator polynomial from its roots */ - $rs->genpoly = array_fill(0, $nroots+1, 0); - - $rs->fcr = $fcr; - $rs->prim = $prim; - $rs->nroots = $nroots; - $rs->gfpoly = $gfpoly; - - /* Find prim-th root of 1, used in decoding */ - for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn) - ; // intentional empty-body loop! - - $rs->iprim = (int)($iprim / $prim); - $rs->genpoly[0] = 1; - - for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) { - $rs->genpoly[$i+1] = 1; - - // Multiply rs->genpoly[] by @**(root + x) - for ($j = $i; $j > 0; $j--) { - if ($rs->genpoly[$j] != 0) { - $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)]; - } else { - $rs->genpoly[$j] = $rs->genpoly[$j-1]; - } - } - // rs->genpoly[0] can never be zero - $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)]; - } - - // convert rs->genpoly[] to index form for quicker encoding - for ($i = 0; $i <= $nroots; $i++) - $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]]; - - return $rs; - } - - //---------------------------------------------------------------------- - public function encode_rs_char($data, &$parity) - { - $MM =& $this->mm; - $NN =& $this->nn; - $ALPHA_TO =& $this->alpha_to; - $INDEX_OF =& $this->index_of; - $GENPOLY =& $this->genpoly; - $NROOTS =& $this->nroots; - $FCR =& $this->fcr; - $PRIM =& $this->prim; - $IPRIM =& $this->iprim; - $PAD =& $this->pad; - $A0 =& $NN; - - $parity = array_fill(0, $NROOTS, 0); - - for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) { - - $feedback = $INDEX_OF[$data[$i] ^ $parity[0]]; - if($feedback != $A0) { - // feedback term is non-zero - - // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must - // always be for the polynomials constructed by init_rs() - $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback); - - for($j=1;$j<$NROOTS;$j++) { - $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])]; - } - } - - // Shift - array_shift($parity); - if($feedback != $A0) { - array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]); - } else { - array_push($parity, 0); - } - } - } - } - - //########################################################################## - - class QRrs { - - public static $items = array(); - - //---------------------------------------------------------------------- - public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad) - { - foreach(self::$items as $rs) { - if($rs->pad != $pad) continue; - if($rs->nroots != $nroots) continue; - if($rs->mm != $symsize) continue; - if($rs->gfpoly != $gfpoly) continue; - if($rs->fcr != $fcr) continue; - if($rs->prim != $prim) continue; - - return $rs; - } - - $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad); - array_unshift(self::$items, $rs); - - return $rs; - } - } - - - -//---- qrmask.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Masking - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - define('N1', 3); - define('N2', 3); - define('N3', 40); - define('N4', 10); - - class QRmask { - - public $runLength = array(); - - //---------------------------------------------------------------------- - public function __construct() - { - $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0); - } - - //---------------------------------------------------------------------- - public function writeFormatInformation($width, &$frame, $mask, $level) - { - $blacks = 0; - $format = QRspec::getFormatInfo($mask, $level); - - for($i=0; $i<8; $i++) { - if($format & 1) { - $blacks += 2; - $v = 0x85; - } else { - $v = 0x84; - } - - $frame[8][$width - 1 - $i] = chr($v); - if($i < 6) { - $frame[$i][8] = chr($v); - } else { - $frame[$i + 1][8] = chr($v); - } - $format = $format >> 1; - } - - for($i=0; $i<7; $i++) { - if($format & 1) { - $blacks += 2; - $v = 0x85; - } else { - $v = 0x84; - } - - $frame[$width - 7 + $i][8] = chr($v); - if($i == 0) { - $frame[8][7] = chr($v); - } else { - $frame[8][6 - $i] = chr($v); - } - - $format = $format >> 1; - } - - return $blacks; - } - - //---------------------------------------------------------------------- - public function mask0($x, $y) { return ($x+$y)&1; } - public function mask1($x, $y) { return ($y&1); } - public function mask2($x, $y) { return ($x%3); } - public function mask3($x, $y) { return ($x+$y)%3; } - public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; } - public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3; } - public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1; } - public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1; } - - //---------------------------------------------------------------------- - private function generateMaskNo($maskNo, $width, $frame) - { - $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); - - for($y=0; $y<$width; $y++) { - for($x=0; $x<$width; $x++) { - if(ord($frame[$y][$x]) & 0x80) { - $bitMask[$y][$x] = 0; - } else { - $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y); - $bitMask[$y][$x] = ($maskFunc == 0)?1:0; - } - - } - } - - return $bitMask; - } - - //---------------------------------------------------------------------- - public static function serial($bitFrame) - { - $codeArr = array(); - - foreach ($bitFrame as $line) - $codeArr[] = join('', $line); - - return gzcompress(join("\n", $codeArr), 9); - } - - //---------------------------------------------------------------------- - public static function unserial($code) - { - $codeArr = array(); - - $codeLines = explode("\n", gzuncompress($code)); - foreach ($codeLines as $line) - $codeArr[] = str_split($line); - - return $codeArr; - } - - //---------------------------------------------------------------------- - public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) - { - $b = 0; - $bitMask = array(); - - $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; - - if (QR_CACHEABLE) { - if (file_exists($fileName)) { - $bitMask = self::unserial(file_get_contents($fileName)); - } else { - $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); - if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) - mkdir(QR_CACHE_DIR.'mask_'.$maskNo); - file_put_contents($fileName, self::serial($bitMask)); - } - } else { - $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); - } - - if ($maskGenOnly) - return; - - $d = $s; - - for($y=0; $y<$width; $y++) { - for($x=0; $x<$width; $x++) { - if($bitMask[$y][$x] == 1) { - $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); - } - $b += (int)(ord($d[$y][$x]) & 1); - } - } - - return $b; - } - - //---------------------------------------------------------------------- - public function makeMask($width, $frame, $maskNo, $level) - { - $masked = array_fill(0, $width, str_repeat("\0", $width)); - $this->makeMaskNo($maskNo, $width, $frame, $masked); - $this->writeFormatInformation($width, $masked, $maskNo, $level); - - return $masked; - } - - //---------------------------------------------------------------------- - public function calcN1N3($length) - { - $demerit = 0; - - for($i=0; $i<$length; $i++) { - - if($this->runLength[$i] >= 5) { - $demerit += (N1 + ($this->runLength[$i] - 5)); - } - if($i & 1) { - if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { - $fact = (int)($this->runLength[$i] / 3); - if(($this->runLength[$i-2] == $fact) && - ($this->runLength[$i-1] == $fact) && - ($this->runLength[$i+1] == $fact) && - ($this->runLength[$i+2] == $fact)) { - if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { - $demerit += N3; - } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { - $demerit += N3; - } - } - } - } - } - return $demerit; - } - - //---------------------------------------------------------------------- - public function evaluateSymbol($width, $frame) - { - $head = 0; - $demerit = 0; - - for($y=0; $y<$width; $y++) { - $head = 0; - $this->runLength[0] = 1; - - $frameY = $frame[$y]; - - if ($y>0) - $frameYM = $frame[$y-1]; - - for($x=0; $x<$width; $x++) { - if(($x > 0) && ($y > 0)) { - $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); - $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); - - if(($b22 | ($w22 ^ 1))&1) { - $demerit += N2; - } - } - if(($x == 0) && (ord($frameY[$x]) & 1)) { - $this->runLength[0] = -1; - $head = 1; - $this->runLength[$head] = 1; - } else if($x > 0) { - if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { - $head++; - $this->runLength[$head] = 1; - } else { - $this->runLength[$head]++; - } - } - } - - $demerit += $this->calcN1N3($head+1); - } - - for($x=0; $x<$width; $x++) { - $head = 0; - $this->runLength[0] = 1; - - for($y=0; $y<$width; $y++) { - if($y == 0 && (ord($frame[$y][$x]) & 1)) { - $this->runLength[0] = -1; - $head = 1; - $this->runLength[$head] = 1; - } else if($y > 0) { - if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { - $head++; - $this->runLength[$head] = 1; - } else { - $this->runLength[$head]++; - } - } - } - - $demerit += $this->calcN1N3($head+1); - } - - return $demerit; - } - - - //---------------------------------------------------------------------- - public function mask($width, $frame, $level) - { - $minDemerit = PHP_INT_MAX; - $bestMaskNum = 0; - $bestMask = array(); - - $checked_masks = array(0,1,2,3,4,5,6,7); - - if (QR_FIND_FROM_RANDOM !== false) { - - $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9); - for ($i = 0; $i < $howManuOut; $i++) { - $remPos = rand (0, count($checked_masks)-1); - unset($checked_masks[$remPos]); - $checked_masks = array_values($checked_masks); - } - - } - - $bestMask = $frame; - - foreach($checked_masks as $i) { - $mask = array_fill(0, $width, str_repeat("\0", $width)); - - $demerit = 0; - $blacks = 0; - $blacks = $this->makeMaskNo($i, $width, $frame, $mask); - $blacks += $this->writeFormatInformation($width, $mask, $i, $level); - $blacks = (int)(100 * $blacks / ($width * $width)); - $demerit = (int)((int)(abs($blacks - 50) / 5) * N4); - $demerit += $this->evaluateSymbol($width, $mask); - - if($demerit < $minDemerit) { - $minDemerit = $demerit; - $bestMask = $mask; - $bestMaskNum = $i; - } - } - - return $bestMask; - } - - //---------------------------------------------------------------------- - } - - - - -//---- qrencode.php ----------------------------- - - - - -/* - * PHP QR Code encoder - * - * Main encoder classes. - * - * Based on libqrencode C library distributed under LGPL 2.1 - * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi - * - * PHP QR Code is distributed under LGPL 3 - * Copyright (C) 2010 Dominik Dzienia - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - class QRrsblock { - public $dataLength; - public $data = array(); - public $eccLength; - public $ecc = array(); - - public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs) - { - $rs->encode_rs_char($data, $ecc); - - $this->dataLength = $dl; - $this->data = $data; - $this->eccLength = $el; - $this->ecc = $ecc; - } - }; - - //########################################################################## - - class QRrawcode { - public $version; - public $datacode = array(); - public $ecccode = array(); - public $blocks; - public $rsblocks = array(); //of RSblock - public $count; - public $dataLength; - public $eccLength; - public $b1; - - //---------------------------------------------------------------------- - public function __construct(QRinput $input) - { - $spec = array(0,0,0,0,0); - - $this->datacode = $input->getByteStream(); - if(is_null($this->datacode)) { - throw new Exception('null imput string'); - } - - QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec); - - $this->version = $input->getVersion(); - $this->b1 = QRspec::rsBlockNum1($spec); - $this->dataLength = QRspec::rsDataLength($spec); - $this->eccLength = QRspec::rsEccLength($spec); - $this->ecccode = array_fill(0, $this->eccLength, 0); - $this->blocks = QRspec::rsBlockNum($spec); - - $ret = $this->init($spec); - if($ret < 0) { - throw new Exception('block alloc error'); - return null; - } - - $this->count = 0; - } - - //---------------------------------------------------------------------- - public function init(array $spec) - { - $dl = QRspec::rsDataCodes1($spec); - $el = QRspec::rsEccCodes1($spec); - $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); - - - $blockNo = 0; - $dataPos = 0; - $eccPos = 0; - for($i=0; $iecccode,$eccPos); - $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); - $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); - - $dataPos += $dl; - $eccPos += $el; - $blockNo++; - } - - if(QRspec::rsBlockNum2($spec) == 0) - return 0; - - $dl = QRspec::rsDataCodes2($spec); - $el = QRspec::rsEccCodes2($spec); - $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); - - if($rs == NULL) return -1; - - for($i=0; $iecccode,$eccPos); - $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); - $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc); - - $dataPos += $dl; - $eccPos += $el; - $blockNo++; - } - - return 0; - } - - //---------------------------------------------------------------------- - public function getCode() - { - $ret; - - if($this->count < $this->dataLength) { - $row = $this->count % $this->blocks; - $col = $this->count / $this->blocks; - if($col >= $this->rsblocks[0]->dataLength) { - $row += $this->b1; - } - $ret = $this->rsblocks[$row]->data[$col]; - } else if($this->count < $this->dataLength + $this->eccLength) { - $row = ($this->count - $this->dataLength) % $this->blocks; - $col = ($this->count - $this->dataLength) / $this->blocks; - $ret = $this->rsblocks[$row]->ecc[$col]; - } else { - return 0; - } - $this->count++; - - return $ret; - } - } - - //########################################################################## - - class QRcode { - - public $version; - public $width; - public $data; - - //---------------------------------------------------------------------- - public function encodeMask(QRinput $input, $mask) - { - if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { - throw new Exception('wrong version'); - } - if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { - throw new Exception('wrong level'); - } - - $raw = new QRrawcode($input); - - QRtools::markTime('after_raw'); - - $version = $raw->version; - $width = QRspec::getWidth($version); - $frame = QRspec::newFrame($version); - - $filler = new FrameFiller($width, $frame); - if(is_null($filler)) { - return NULL; - } - - // inteleaved data and ecc codes - for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) { - $code = $raw->getCode(); - $bit = 0x80; - for($j=0; $j<8; $j++) { - $addr = $filler->next(); - $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0)); - $bit = $bit >> 1; - } - } - - QRtools::markTime('after_filler'); - - unset($raw); - - // remainder bits - $j = QRspec::getRemainder($version); - for($i=0; $i<$j; $i++) { - $addr = $filler->next(); - $filler->setFrameAt($addr, 0x02); - } - - $frame = $filler->frame; - unset($filler); - - - // masking - $maskObj = new QRmask(); - if($mask < 0) { - - if (QR_FIND_BEST_MASK) { - $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); - } else { - $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel()); - } - } else { - $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); - } - - if($masked == NULL) { - return NULL; - } - - QRtools::markTime('after_mask'); - - $this->version = $version; - $this->width = $width; - $this->data = $masked; - - return $this; - } - - //---------------------------------------------------------------------- - public function encodeInput(QRinput $input) - { - return $this->encodeMask($input, -1); - } - - //---------------------------------------------------------------------- - public function encodeString8bit($string, $version, $level) - { - if(string == NULL) { - throw new Exception('empty string!'); - return NULL; - } - - $input = new QRinput($version, $level); - if($input == NULL) return NULL; - - $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string)); - if($ret < 0) { - unset($input); - return NULL; - } - return $this->encodeInput($input); - } - - //---------------------------------------------------------------------- - public function encodeString($string, $version, $level, $hint, $casesensitive) - { - - if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) { - throw new Exception('bad hint'); - return NULL; - } - - $input = new QRinput($version, $level); - if($input == NULL) return NULL; - - $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive); - if($ret < 0) { - return NULL; - } - - return $this->encodeInput($input); - } - - //---------------------------------------------------------------------- - public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encodePNG($text, $outfile, $saveandprint=false); - } - - //---------------------------------------------------------------------- - public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encode($text, $outfile); - } - - //---------------------------------------------------------------------- - public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = QRencode::factory($level, $size, $margin); - return $enc->encodeRAW($text, $outfile); - } - } - - //########################################################################## - - class FrameFiller { - - public $width; - public $frame; - public $x; - public $y; - public $dir; - public $bit; - - //---------------------------------------------------------------------- - public function __construct($width, &$frame) - { - $this->width = $width; - $this->frame = $frame; - $this->x = $width - 1; - $this->y = $width - 1; - $this->dir = -1; - $this->bit = -1; - } - - //---------------------------------------------------------------------- - public function setFrameAt($at, $val) - { - $this->frame[$at['y']][$at['x']] = chr($val); - } - - //---------------------------------------------------------------------- - public function getFrameAt($at) - { - return ord($this->frame[$at['y']][$at['x']]); - } - - //---------------------------------------------------------------------- - public function next() - { - do { - - if($this->bit == -1) { - $this->bit = 0; - return array('x'=>$this->x, 'y'=>$this->y); - } - - $x = $this->x; - $y = $this->y; - $w = $this->width; - - if($this->bit == 0) { - $x--; - $this->bit++; - } else { - $x++; - $y += $this->dir; - $this->bit--; - } - - if($this->dir < 0) { - if($y < 0) { - $y = 0; - $x -= 2; - $this->dir = 1; - if($x == 6) { - $x--; - $y = 9; - } - } - } else { - if($y == $w) { - $y = $w - 1; - $x -= 2; - $this->dir = -1; - if($x == 6) { - $x--; - $y -= 8; - } - } - } - if($x < 0 || $y < 0) return null; - - $this->x = $x; - $this->y = $y; - - } while(ord($this->frame[$y][$x]) & 0x80); - - return array('x'=>$x, 'y'=>$y); - } - - } ; - - //########################################################################## - - class QRencode { - - public $casesensitive = true; - public $eightbit = false; - - public $version = 0; - public $size = 3; - public $margin = 4; - - public $structured = 0; // not supported yet - - public $level = QR_ECLEVEL_L; - public $hint = QR_MODE_8; - - //---------------------------------------------------------------------- - public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4) - { - $enc = new QRencode(); - $enc->size = $size; - $enc->margin = $margin; - - switch ($level.'') { - case '0': - case '1': - case '2': - case '3': - $enc->level = $level; - break; - case 'l': - case 'L': - $enc->level = QR_ECLEVEL_L; - break; - case 'm': - case 'M': - $enc->level = QR_ECLEVEL_M; - break; - case 'q': - case 'Q': - $enc->level = QR_ECLEVEL_Q; - break; - case 'h': - case 'H': - $enc->level = QR_ECLEVEL_H; - break; - } - - return $enc; - } - - //---------------------------------------------------------------------- - public function encodeRAW($intext, $outfile = false) - { - $code = new QRcode(); - - if($this->eightbit) { - $code->encodeString8bit($intext, $this->version, $this->level); - } else { - $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); - } - - return $code->data; - } - - //---------------------------------------------------------------------- - public function encode($intext, $outfile = false) - { - $code = new QRcode(); - - if($this->eightbit) { - $code->encodeString8bit($intext, $this->version, $this->level); - } else { - $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive); - } - - QRtools::markTime('after_encode'); - - if ($outfile!== false) { - file_put_contents($outfile, join("\n", QRtools::binarize($code->data))); - } else { - return QRtools::binarize($code->data); - } - } - - //---------------------------------------------------------------------- - public function encodePNG($intext, $outfile = false,$saveandprint=false) - { - try { - - ob_start(); - $tab = $this->encode($intext); - $err = ob_get_contents(); - ob_end_clean(); - - if ($err != '') - QRtools::log($outfile, $err); - - $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin)); - - QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint); - - } catch (Exception $e) { - - QRtools::log($outfile, $e->getMessage()); - - } - } - } - - diff --git a/apps/shorty/ajax/add.php b/apps/shorty/ajax/add.php deleted file mode 100644 index b1130e47db..0000000000 --- a/apps/shorty/ajax/add.php +++ /dev/null @@ -1,101 +0,0 @@ - -* @license GNU AFFERO GENERAL PUBLIC LICENSE (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/add.php - * @brief Ajax method to add a new shorty defined by request arguments - * @param title (string) Human readable title of the shorty - * @param target (url) Remote target url meant to be shortened - * @param until (date) Date until when the created shorty is valid and usable - * @param notes (string) Any additional information in text form - * @param favicon (url) Reference to the shortcut icon used in target url - * @returns (json) success/error state indicator - * @returns (json) Associative array of attributes of the generated shorty - * @returns (json) Human readable message - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - - //no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $p_id = OC_Shorty_Tools::shorty_id ( ); - $p_status = OC_Shorty_Type::req_argument ( 'status', OC_Shorty_Type::STATUS, FALSE ); - $p_title = OC_Shorty_Type::req_argument ( 'title', OC_Shorty_Type::STRING, FALSE ); - $p_target = OC_Shorty_Type::req_argument ( 'target', OC_Shorty_Type::URL, TRUE ); - $p_until = OC_Shorty_Type::req_argument ( 'until', OC_Shorty_Type::DATE, FALSE ); - $p_notes = OC_Shorty_Type::req_argument ( 'notes', OC_Shorty_Type::STRING, FALSE ); - $p_favicon = OC_Shorty_Type::req_argument ( 'favicon', OC_Shorty_Type::URL, FALSE ); - // register shorty at backend - $p_source = OC_Shorty_Backend::registerUrl ( $p_id ); - // fallback title: choose hostname if no title is specified - $p_title = $p_title ? trim($p_title) : parse_url($p_target,PHP_URL_HOST); - // insert new shorty into our database - $param = array - ( - ':user' => OCP\User::getUser(), - ':id' => $p_id, - ':status' => $p_status ? $p_status : '', - ':title' => $p_title ? $p_title : '', - ':favicon' => $p_favicon ? $p_favicon : '', - ':source' => $p_source ? $p_source : '', - ':target' => $p_target ? $p_target : '', - ':notes' => $p_notes ? $p_notes : '', - ':until' => $p_until, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_INSERT ); - $query->execute ( $param ); - - // read new entry for feedback - $param = array - ( - ':user' => OCP\User::getUser(), - ':id' => $p_id, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_VERIFY ); - $entries = $query->execute($param)->FetchAll(); - if ( (1==count($entries)) - &&(isset($entries[0]['id'])) - &&($p_id==$entries[0]['id']) ) - $entries[0]['relay']=OC_Shorty_Tools::relayUrl ( $entries[0]['id'] ); - else - throw new OC_Shorty_Exception ( "failed to verify stored shorty with id '%1s'", array($p_id) ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Url shortened to: %s",$p_source), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => $entries[0], - 'message' => OC_Shorty_L10n::t("Url shortened to: %s",$p_source) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/click.php b/apps/shorty/ajax/click.php deleted file mode 100644 index c88f6eec4f..0000000000 --- a/apps/shorty/ajax/click.php +++ /dev/null @@ -1,67 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/click.php - * @brief Ajax method to register a 'click', a single hit on an existing and valid shorty - * @param id (string) Internal id of a referenced shorty - * @returns (json) success/error state indicator - * @returns (json) Associative array holding the id of the shorty whose click was registered - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - if (isset($_GET['id'])) - { - $p_id = OC_Shorty_Type::req_argument ( $_GET['id'], OC_Shorty_Type::ID, TRUE ); - $param = array - ( - 'user' => OCP\User::getUser(), - 'id' => $p_id, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_CLICK ); - $query->execute ( $param ); - OCP\JSON::success ( array ( 'data' => array('id'=>$p_id), - 'message' => OC_Shorty_L10n::t('Click registered') ) ); - } - else - throw new OC_Shorty_Exception ( "request failed: missing mandatory argument 'id'" ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/count.php b/apps/shorty/ajax/count.php deleted file mode 100644 index 9a00083bb9..0000000000 --- a/apps/shorty/ajax/count.php +++ /dev/null @@ -1,54 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/count.php - * @brief Ajax method to retrieve a list of important sums, counts of the existing set of shortys - * @returns (json) success/error state indicator - * @returns (json) Associative array of counts - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = TRUE; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $countResult = OC_Shorty_Tools::countShorties ( ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\JSON::success ( array ( 'data' => $countResult, - 'message' => OC_Shorty_L10n::t('Counted entries and clicks') ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/del.php b/apps/shorty/ajax/del.php deleted file mode 100644 index b24f83915e..0000000000 --- a/apps/shorty/ajax/del.php +++ /dev/null @@ -1,63 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/del.php - * @brief Ajax method to delete an existing shorty - * @param id (string) Internal id of a referenced shorty - * @returns (json) success/error state indicator - * @returns (json) Key of shorty that was deleted - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $p_id = OC_Shorty_Type::req_argument ( 'id', OC_Shorty_Type::ID, TRUE ); - $param = array - ( - 'user' => OCP\User::getUser(), - 'id' => $p_id, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_DELETE ); - $query->execute($param); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Shorty with id '%s' deleted",$p_id), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => array('id'=>$p_id), - 'message' => OC_Shorty_L10n::t("Shorty with id '%s' deleted",$p_id) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/edit.php b/apps/shorty/ajax/edit.php deleted file mode 100644 index 252e4fe5c2..0000000000 --- a/apps/shorty/ajax/edit.php +++ /dev/null @@ -1,88 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/edit.php - * @brief Ajax method to modify aspects of an existing shorty - * @param id (string) Internal id of the referenced shorty - * @param title (string) Human readable title - * @param notes (string) Any additional information in free text form - * @returns (json) success/error state indicator - * @returns (json) Associative array holding the id of the shorty whose click was registered - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $p_id = OC_Shorty_Type::req_argument ( 'id', OC_Shorty_Type::ID, TRUE ); - $p_status = OC_Shorty_Type::req_argument ( 'status', OC_Shorty_Type::STATUS, FALSE ); - $p_title = OC_Shorty_Type::req_argument ( 'title', OC_Shorty_Type::STRING, FALSE ); - $p_until = OC_Shorty_Type::req_argument ( 'until', OC_Shorty_Type::DATE, FALSE ); - $p_notes = OC_Shorty_Type::req_argument ( 'notes', OC_Shorty_Type::STRING, FALSE ); - $param = array - ( - ':user' => OCP\User::getUser ( ), - ':id' => $p_id, - ':status'=> $p_status ? $p_status : '', - ':title' => $p_title ? $p_title : '', - ':notes' => $p_notes ? $p_notes : '', - ':until' => $p_until, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_UPDATE ); - $query->execute ( $param ); - - // read new entry for feedback - $param = array - ( - 'user' => OCP\User::getUser(), - 'id' => $p_id, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_VERIFY ); - $entries = $query->execute($param)->FetchAll(); - if ( (1==count($entries)) - &&(isset($entries[0]['id'])) - &&($p_id==$entries[0]['id']) ) - $entries[0]['relay']=OC_Shorty_Tools::relayUrl ( $entries[0]['id'] ); - else - throw new OC_Shorty_Exception ( "failed to verify stored shorty with id '%1s'", array($p_id) ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Modifications for shorty with id '%s' saved",$p_id), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => $entries[0], - 'message' => OC_Shorty_L10n::t("Modifications for shorty with id '%s' saved",$p_id) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/list.php b/apps/shorty/ajax/list.php deleted file mode 100644 index 8b4e9b3e81..0000000000 --- a/apps/shorty/ajax/list.php +++ /dev/null @@ -1,77 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/list.php - * @brief Ajax method to retrieve a list of existing shortys - * @returns (json) success/error state indicator - * @returns (number) Total number of shortys in the list - * @returns (json) Numeric array of all shortys, associative array of attributes as values for every single shorty contained - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = TRUE; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - // first remove any entries already marked as 'deleted' - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_REMOVE ); - $result = $query->execute(array(':user'=>OCP\User::getUser())); - // now comes the real list selection -// define ('PAGE_SIZE', 100); -// $p_offset = OC_Shorty_Type::req_argument ( 'page', OC_Shorty_Type::INTEGER, FALSE) * PAGE_SIZE; - // pre-sort list according to user preferences - $p_sort = OC_Shorty_Type::$SORTING[OCP\Config::getUserValue(OCP\User::getUser(),'shorty','list-sort-code','cd')]; - $param = array - ( - ':user' => OCP\User::getUser ( ), - ':sort' => $p_sort, -// ':offset' => $p_offset, -// ':limit' => PAGE_SIZE, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_LIST ); - $result = $query->execute($param); - $reply = $result->fetchAll(); - // enhance all entries with the relay url - foreach (array_keys($reply) as $key) - if (isset($reply[$key]['id'])) - $reply[$key]['relay']=OC_Shorty_Tools::relayUrl ( $reply[$key]['id'] ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\JSON::success ( array ( 'data' => $reply, - 'count' => sizeof($reply), - 'message' => OC_Shorty_L10n::t('Number of entries: %s', count($reply)) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/meta.php b/apps/shorty/ajax/meta.php deleted file mode 100644 index 5f9d5c3c31..0000000000 --- a/apps/shorty/ajax/meta.php +++ /dev/null @@ -1,56 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/meta.php - * @brief Ajax method to query meta information about a given remote url - * @param target (string) Url of a remote web resource - * @returns (json) success/error state indicator - * @returns (array) Associative array of meta data aspects - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $target = OC_Shorty_Type::req_argument ( 'target', OC_Shorty_Type::URL, TRUE ); - $meta = OC_Shorty_Meta::fetchMetaData(htmlspecialchars_decode($target)); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\JSON::success ( array ( 'data' => $meta, - 'message' => OC_Shorty_L10n::t("Target url '%s' is valid", $meta['target']) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/preferences.php b/apps/shorty/ajax/preferences.php deleted file mode 100644 index e35a2f7aff..0000000000 --- a/apps/shorty/ajax/preferences.php +++ /dev/null @@ -1,119 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/preferences.php - * @brief Ajax method to store one or more personal preferences - * @param backend-type (string) Identifier of chosen backend type - * @param backend-static-base (string) Url to use as a base when the static backend is active - * @param backend-google-key (string) Personal authentication key to use when the google backend is active - * @param backend-bitly-key (string) Personal authentication key to use when the bit.li backend is active - * @param backend-bitly-user (string) Personal authentication user to use when the bit.li backend is active - * @param sms-control (string) Controls wether a 'send as sms' action should be offered is the sharing dialog - * @param list-sort-code (string) Two character sorting key controlling the active sorting of shorty lists - * @returns (json) success/error state indicator - * @returns (json) Associative array holding the stored values by their key - * @returns (json) Human readable message describing the result - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $data = array(); - switch ( $_SERVER['REQUEST_METHOD'] ) - { - case 'POST': - // detect provided preferences - $data = array(); - foreach (array_keys($_POST) as $key) - if ( isset(OC_Shorty_Type::$PREFERENCE[$key]) ) // ignore unknown preference keys - { - $type = OC_Shorty_Type::$PREFERENCE[$key]; - $data[$key] = OC_Shorty_Type::req_argument ( $key, $type, FALSE ); - } - // eliminate settings not explicitly set - $data = array_diff ( $data, array(FALSE) ); - // store settings - foreach ( $data as $key=>$val ) - OCP\Config::setUserValue( OCP\User::getUser(), 'shorty', $key, $val ); - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Preference(s) '%s' saved.",implode(',',array_keys($data))), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => $data, - 'message' => OC_Shorty_L10n::t("Preference(s) '%s' saved.",implode(',',array_keys($data))) ) ); - break; - case 'GET': - // detect requested preferences - foreach (array_keys($_GET) as $key) - { - if ( isset(OC_Shorty_Type::$PREFERENCE[$key]) ) // ignore unknown preference keys - { - $type = OC_Shorty_Type::$PREFERENCE[$key]; - $data[$key] = OCP\Config::getUserValue( OCP\User::getUser(), 'shorty', $key); - // morph value into an explicit type - switch ($type) - { - case OC_Shorty_Type::ID: - case OC_Shorty_Type::STATUS: - case OC_Shorty_Type::SORTKEY: - case OC_Shorty_Type::SORTVAL: - case OC_Shorty_Type::STRING: - case OC_Shorty_Type::URL: - case OC_Shorty_Type::DATE: - settype ( $data[$key], 'string' ); - break; - case OC_Shorty_Type::INTEGER: - case OC_Shorty_Type::TIMESTAMP: - settype ( $data[$key], 'integer' ); - break; - case OC_Shorty_Type::FLOAT: - settype ( $data[$key], 'float' ); - break; - default: - } // switch - } - } // foreach - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Preference(s) '%s' saved.",implode(',',array_keys($data))), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => $data, - 'message' => OC_Shorty_L10n::t('Preference(s) retrieved.') ) ); - break; - default: - throw new OC_Shorty_Exception ( "unexpected request method '%s'", $_SERVER['REQUEST_METHOD'] ); - } // switch -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/settings.php b/apps/shorty/ajax/settings.php deleted file mode 100644 index af76b69e07..0000000000 --- a/apps/shorty/ajax/settings.php +++ /dev/null @@ -1,109 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/settings.php - * @brief Ajax method to store one or more system settings (plugin settings) - * @param backend-static-base (string) Url to use as a base when the static backend is active (plugins default, may be overridden by user preference) - * @returns (json) success/error state indicator - * @returns (json) Associative array holding the stored values by their key - * @returns (json) Human readable message describing the result - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkAdminUser ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $data = array(); - switch ( $_SERVER['REQUEST_METHOD'] ) - { - case 'POST': - // detect provided settings - $data = array(); - foreach (array_keys($_POST) as $key) - if ( isset(OC_Shorty_Type::$SETTING[$key]) ) // ignore unknown preference keys - { - $type = OC_Shorty_Type::$SETTING[$key]; - $data[$key] = OC_Shorty_Type::req_argument ( $key, $type, FALSE ); - } - // eliminate settings not explicitly set - $data = array_diff ( $data, array(FALSE) ); - // store settings one by one - foreach ( $data as $key=>$val ) - OCP\Config::setAppValue( 'shorty', $key, $val ); - break; - case 'GET': - // detect requested settings - foreach (array_keys($_GET) as $key) - { - if ( isset(OC_Shorty_Type::$SETTING[$key]) ) // ignore unknown preference keys - { - $type = OC_Shorty_Type::$SETTING[$key]; - $data[$key] = OCP\Config::getUserValue( OCP\User::getUser(), 'shorty', $key); - // morph value into an explicit type - switch ($type) - { - case OC_Shorty_Type::ID: - case OC_Shorty_Type::STATUS: - case OC_Shorty_Type::SORTKEY: - case OC_Shorty_Type::SORTVAL: - case OC_Shorty_Type::STRING: - case OC_Shorty_Type::URL: - case OC_Shorty_Type::DATE: - settype ( $data[$key], 'string' ); - break; - case OC_Shorty_Type::INTEGER: - case OC_Shorty_Type::TIMESTAMP: - settype ( $data[$key], 'integer' ); - break; - case OC_Shorty_Type::FLOAT: - settype ( $data[$key], 'float' ); - break; - default: - } // switch - } - } // foreach - break; - default: - throw new OC_Shorty_Exception ( "unexpected request method '%s'", $_SERVER['REQUEST_METHOD'] ); - } // switch - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Setting(s) '%s' saved.",implode(',',array_keys($data))), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => $data, - 'message' => OC_Shorty_L10n::t('Setting saved.') ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/ajax/status.php b/apps/shorty/ajax/status.php deleted file mode 100644 index 6d00bf5885..0000000000 --- a/apps/shorty/ajax/status.php +++ /dev/null @@ -1,67 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file ajax/status.php - * @brief Ajax method to modify the status of an existing shorty - * @param id (string) Internal id of the referenced shorty - * @param title (string) Human readable title - * @param notes (string) Any additional information in free text form - * @returns (json) success/error state indicator - * @returns (json) Associative array holding the id of the shorty whose click was registered - * @author Christian Reiner - */ - -// swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure -OC_Shorty_Tools::ob_control ( TRUE ); - -//no apps or filesystem -$RUNTIME_NOSETUPFS = true; - -// Check if we are a user -OCP\JSON::checkLoggedIn ( ); -OCP\JSON::checkAppEnabled ( 'shorty' ); - -try -{ - $p_id = OC_Shorty_Type::req_argument ( 'id', OC_Shorty_Type::ID, TRUE ); - $p_status = OC_Shorty_Type::req_argument ( 'status', OC_Shorty_Type::STATUS, FALSE ); - $param = array - ( - 'user' => OCP\User::getUser ( ), - 'id' => $p_id, - 'status' => $p_status, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_STATUS ); - $query->execute ( $param ); - - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - OC_Shorty_Tools::ob_control ( FALSE ); - OCP\Util::writeLog( 'shorty', sprintf("Status change for shorty with id '%s' saved",$p_id), OC_Log::INFO ); - OCP\JSON::success ( array ( 'data' => array('id'=>$p_id), - 'message' => sprintf(OC_Shorty_L10n::t("Status change for shorty with id '%s' saved"),$p_id) ) ); -} catch ( Exception $e ) { OC_Shorty_Exception::JSONerror($e); } -?> diff --git a/apps/shorty/appinfo/app.php b/apps/shorty/appinfo/app.php deleted file mode 100644 index 635fda4ee2..0000000000 --- a/apps/shorty/appinfo/app.php +++ /dev/null @@ -1,53 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file appinfo/app.php - * @brief Basic registration of plugin at ownCloud - * @author Christian Reiner - */ - -OC::$CLASSPATH['OC_Shorty_Backend'] = 'apps/shorty/lib/backend.php'; -OC::$CLASSPATH['OC_Shorty_Exception'] = 'apps/shorty/lib/exception.php'; -OC::$CLASSPATH['OC_Shorty_HttpException'] = 'apps/shorty/lib/exception.php'; -OC::$CLASSPATH['OC_Shorty_L10n'] = 'apps/shorty/lib/l10n.php'; -OC::$CLASSPATH['OC_Shorty_Meta'] = 'apps/shorty/lib/meta.php'; -OC::$CLASSPATH['OC_Shorty_Query'] = 'apps/shorty/lib/query.php'; -OC::$CLASSPATH['OC_Shorty_Tools'] = 'apps/shorty/lib/tools.php'; -OC::$CLASSPATH['OC_Shorty_Type'] = 'apps/shorty/lib/type.php'; - -OCP\App::addNavigationEntry ( array ( 'id' => 'shorty_index', - 'order' => 71, - 'href' => OCP\Util::linkTo ( 'shorty', 'index.php' ), - 'icon' => OCP\Util::imagePath( 'shorty', 'shorty.svg' ), - 'name' => 'Shorty' ) ); - -OCP\App::register ( array ( 'order' => 71, 'id' => 'shorty', 'name' => 'Shorty' ) ); -OCP\App::registerAdmin ( 'shorty', 'settings' ); -OCP\App::registerPersonal ( 'shorty', 'preferences' ); -OCP\Util::connectHook ( 'OC_User', 'post_deleteUser', 'OC_Shorty_Hooks', 'deleteUser'); - -?> diff --git a/apps/shorty/appinfo/database.xml b/apps/shorty/appinfo/database.xml deleted file mode 100644 index 0cac24dbf2..0000000000 --- a/apps/shorty/appinfo/database.xml +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - *dbname* - true - false - latin1 - - *dbprefix*shorty - - - id - text - true - 12 - - - status - text - 'shared' - true - 10 - - - title - text - '' - true - 80 - - - favicon - text - '' - false - 1024 - - - source - text - true - 4096 - - - target - text - true - 4096 - - - user - text - true - 64 - - - until - date - false - - - - created - date - false - - - - accessed - timestamp - false - - - - clicks - integer - 0 - true - true - 10 - - - notes - text - '' - true - 4096 - - - - shorty_id - true - - id - descending - - - - shorty_user - false - - user - ascending - - - - shorty_source - false - - source - ascending - - - -
      -
      diff --git a/apps/shorty/appinfo/info.xml b/apps/shorty/appinfo/info.xml deleted file mode 100644 index bbee9dd673..0000000000 --- a/apps/shorty/appinfo/info.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - shorty - Shorty - Shorty offers a service to store, manage and use a collection of short links -pointing to ressources in the web. The features are a combination of a -centralized bookmarks collection, an url shortener and an access control. -The collection is presented as a link of "shorties", a shorty can be created -either manually in the list ("New") or by using the "Shortlet". The Shortlet -is something like a Booklet, a JS based bookmark meant to be stored inside the -bookmark toolbar or area of a web browser. When clicked, the page currently -open in the browser will be offered to be added to the list of existing shorties. -For more information see: http://apps.owncloud.com/content/show.php/Shorty?content=150401 -Current version: 0.2.2 (06.06.2012) - 0.2.2 - AGPL - Christian Reiner - 4 - - relay.php - qrcode.php - - diff --git a/apps/shorty/appinfo/migrate.php b/apps/shorty/appinfo/migrate.php deleted file mode 100644 index 5efce251a6..0000000000 --- a/apps/shorty/appinfo/migrate.php +++ /dev/null @@ -1,101 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file appinfo/migrate.php - * @brief OC migration support - * @author Christian Reiner - */ - -class OC_Migration_Provider_Shorty extends OC_Migration_Provider -{ - - function export ( ) - { - OCP\Util::writeLog ( 'migration','starting export for Shorty', OCP\Util::INFO ); - $options = array( - 'table'=>'shorty', - 'matchcol'=>'user', - 'matchval'=>$this->uid, - 'idcol'=>'id' - ); - $ids = $this->content->copyRows( $options ); - $count = OC_Shorty_Tools::countShorties(); - // check for success - if( (is_array($ids) && is_array($count)) - && (count($ids)==$count['sum_shortys']) ) - return true; - else return false; - } // function export - - function import ( ) - { - switch( $this->appinfo->version ) - { - default: - $query = $this->content->prepare( "SELECT * FROM shorty WHERE user_id LIKE ?" ); - $result = $query->execute( array( $this->olduid ) ); - if (is_array(is_array($result))) - { - while( $row = $result->fetchRow() ) - { - $param = array ( - 'id' => $row['id'], - 'status' => $row['status'], - 'title' => $row['title'], - 'favicon' => $row['favicon'], - 'source' => $row['source'], - 'target' => $row['target'], - 'user' => $row['user'], - 'until' => $row['until'], - 'created' => $row['created'], - 'accessed' => $row['accessed'], - 'clicks' => $row['clicks'], - 'notes' => $row['notes'], - ); - // import each shorty one by one, no special treatment required, since no autoincrement id is used - $query = OCP\DB::prepare( sprintf ( "INSERT INTO *PREFIX*shorty(%s) VALUES (%s)", - implode(',',array_keys($param)), - implode(',',array_fill(0,count($param),'?')) ) ); - $query->execute( $param ); - } // while - } // if - break; - } // switch - // check for success by counting the generated entries - $count = OC_Shorty_Tools::countShorties(); - if( (is_array($result) && is_array($count)) - && (count($result)==$count['sum_shortys']) ) - return true; - else return false; - } // function import - -} // class OC_Migration_Provider_Shorty - -// Load the provider -new OC_Migration_Provider_Shorty ( 'shortys' ); - -?> diff --git a/apps/shorty/css/preferences.css b/apps/shorty/css/preferences.css deleted file mode 100644 index 37a86a534a..0000000000 --- a/apps/shorty/css/preferences.css +++ /dev/null @@ -1,109 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file css/preferences.css - * @brief Style definitions for the user preference dialog - * @author Christian Reiner - */ - -#shorty img { - vertical-align: middle; - margin:0; - padding:0; -} -#shorty #shortlet { - outline: medium none; - padding: 0.6em 0.8em; - background-image: -moz-linear-gradient(center bottom, Lavender 0%, white 50%); - border: 1px solid #DDDDDD; - border-radius: 0.5em 0.5em 0.5em 0.5em; - box-shadow: 0 1px 0 #BBBBBB inset; -} -#shorty #shortlet a { - font-style: italic; - color: DarkSlateGray; -} -#shorty #shortlet:after { - content: url("%appswebroot%/apps/shorty/img/drag_me.png"); - position: relative; - top: -12px; - margin-left: -160px; -} -#shorty .chzn-container { - vertical-align: middle; -} - -#shorty .title { - margin-bottom: 0.6em; -} - -#shorty .aspect { - display: inline-block; - font-weight: bold; - width: 6em; - margin: 0 0.2em 0.4em 0; -} - -#shorty .explain { - display: inline-block; - font-style: italic; - margin: 0.3em; -} - -#shorty .example { - font-family: Monospace; - margin: 0.3em; -} - -#shorty a.external { - text-decoration:underline; -} -#shorty a.external:after { - content:url("%appswebroot%/apps/shorty/img/actions/external.png"); - margin-left:0.3em; -} - -#verification #hourglass { - display: block; - text-align: center; - width: 100%; height: 100%; - margin-top: 20px; -} - -#verification #failure { - display: none; - position: absolute; -} - -#verification #success { - display: none; - position: absolute; -} - -#verification legend { - width: 100%; - text-align: center; -} diff --git a/apps/shorty/css/settings.css b/apps/shorty/css/settings.css deleted file mode 100644 index e92031d891..0000000000 --- a/apps/shorty/css/settings.css +++ /dev/null @@ -1,59 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file css/settings.css - * @brief Style definitions for the system settings dialog - * @author Christian Reiner - */ - -#shorty img { - vertical-align: middle; - margin:0; - padding:0; -} -#shorty .aspect { - display: inline-block; - font-weight: bold; - width: 6em; - margin: 0 0.2em 0.4em; -} - -#shorty .explain { - display: inline-block; - font-style: italic; - margin: 0.3em; -} - -#shorty .example { - font-family: Monospace; - margin: 0.3em; - text-decoration: underline; - color: blue; -} - -#shorty .title { - margin-bottom: 0.6em; -} diff --git a/apps/shorty/css/shorty.css b/apps/shorty/css/shorty.css deleted file mode 100644 index b071f06f77..0000000000 --- a/apps/shorty/css/shorty.css +++ /dev/null @@ -1,488 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file css/shorty.css - * @brief Style definitions of the plugins own view - * @author Christian Reiner - */ - -/* everything :-) */ -#content { overflow: auto; } - -/* a case sensitive help button */ -#content #controls #help { -/* float:right; */ -} -/* adapt optical appearance in case the help button is pushed into the header */ -#header #help { - float:right; - background-color:blue; -} - -/* the shorty desktop, a canvas, contains all elements except of those pushed into the header */ -#desktop { - display: inline-block; - position: absolute; -/* width: 100%; height: 100%; */ - background: transparent; - text-align: left; - margin-top: 30px; - padding: 2.5em 0.5em; - padding-top: 20px; -} -/* top bar, holding main control elements */ -#controls { - display: none; -} -/* a dialog for verification of the static backend setup */ -#verification { - overflow: hidden; -} -#verification p { - padding-bottom:0.4em; -} - -/* an activity visualizer, currently a 'rotating timer wheel' */ -#hourglass { - display: none; - position: absolute; - width: 100%; height: 100%; - z-index: 1; - background: transparent; -} -#hourglass img { - margin:4em 8em; -} -/* a replacement list visualized in case the 'real' list is empty */ -#vacuum { - display: none; - position: absolute; - left:8em; top:9em; - width: 100%; height: 100%; - z-index: 2; - white-space: nowrap; - font-style: italic; - background: transparent; -} -.shorty-standalone #busy { - display: none; - float: right; -} - -/* the list of shorties */ -#list { - display: inline; - position: absolute; - z-index: 3; - margin: 0.4em; - background: transparent; - table-layout: fixed; - width: 100%; -} -/* the collapsable toolbar below the lists column title row */ -#list thead #toolbar img { - cursor: pointer; - vertical-align: middle; -} -#list thead #toolbar img.shorty-sorter { - opacity:0.6; -} -/* last column in the list, content usually invisible, except when hovered */ -#list thead #toolbar img.shorty-active { - border:1px solid #888888; - border-radius: 0.3em; -} -#list thead tr:nth-child(2) > th { - padding-bottom:0.5em; -} -/* somewhat more fixed layout for the table */ -#list thead #titlebar th span { - display:inline-block; -} -#list tbody th#title, -#list tbody td#title, -#list tbody th#target, -#list tbody td#target { - width:10em; -} -#list thead #clicks span { - width:3em; -} -#list thead #until span { - width:5em; -} -#list thead #toolbar input, -#list thead #toolbar .chzn-container { - width:6em; - font-size: 11px; - margin: 0; - padding: 0.4em 0.3em 0.2em; - vertical-align: baseline; - background-color:#FFFFFF; -} - -/* column title apeparance */ -#list thead th { - font-weight: bold; - padding: 1px 6px; -} -#list thead th#clicks, -#list thead th#until, -#list thead th#actions { - text-align: center; -} -/* hide the dummy row */ -#list thead tr:last-child { display: none; } -/* hide the content of the 'actions' column, except when being hovered */ -#list tbody tr td span.shorty-actions { - visibility:visible; - opacity:0; - transition: opacity 500ms; - -moz-transition: opacity 500ms; - -webkit-transition: opacity 500ms; - -ms-transition: opacity 500ms; - -o-transition: opacity 500ms; - width:100px; - overflow:auto; -} -#list tbody tr:hover td span.shorty-actions { - opacity:1; - transition: opacity 500ms; - -moz-transition: opacity 500ms; - -webkit-transition: opacity 500ms; - -ms-transition: opacity 500ms; - -o-transition: opacity 500ms; -} -/* highlight a specific, 'clicked' row in the list */ -#list tbody tr.clicked { - border-radius: 0.5em; - background-color:#EEEEEE; - box-shadow: 0 0 0.5px #777777; - transition: background-color 500ms; - -moz-transition: background-color 500ms; - -webkit-transition: background-color 500ms; - -ms-transition: background-color 500ms; - -o-transition: background-color 500ms; -} -/* strike through visible content of rows (entries) marked as deleted */ -#list tbody tr.deleted>#title, -#list tbody tr.deleted>#target, -#list tbody tr.deleted>#clicks, -#list tbody tr.deleted>#until { - color: gray; - text-decoration: line-through; - background: transparent url('%appswebroot%/apps/shorty/img/status/strike.png') 0 50% repeat-x; -} -/* replace the 'delete' action icon by an 'undelete' icon */ -#list tbody tr.deleted>#actions #del:after { - content: url("%appswebroot%/apps/shorty/img/actions/recycle.png"); - position: relative; - top: 3px; - margin-left: -19px; - padding: 0; - opacity: 0; -} -#list tbody tr.deleted:hover>#actions #del>img { - opacity: 0; -} -#list tbody tr.deleted:hover>#actions #del:after { - opacity: 1; -} -/* general table cell appearance */ -#list tbody td { - padding: 1px 6px; -} -#list tbody td#until { - text-align: center; -} -#list tbody td#clicks { - text-align: right; - margin-right: 0.4em; -} -/* prettyfied select boxes */ -#content span.shorty-select select { - width: 6.4em; - margin: 0; - padding: 0.2em; - opacity:0.8; - border:0 none; - font-size: 10px; -} -#content span.shorty-select { - border: 1px solid #DDDDDD; - border-radius: 0.5em 0.5em 0.5em 0.5em; - box-shadow: 0 1px 1px #FFFFFF, 0 1px 0 #BBBBBB inset; - outline: medium none; - padding: 2px; -} -/* general style of interactive dialogs */ -.shorty-dialog { - display: none; - color: black; - border-bottom-left-radius: 1em; - border-bottom-right-radius: 1em; - box-shadow: 0 2px 1px #777777; - vertical-align:middle; - z-index:100; -} -.shorty-dialog fieldset { - position:relative; - border-bottom-left-radius: 0.5em; - border-bottom-right-radius: 0.5em; - border: 1px solid gray; - padding: 2px 4px 8px; -} -.shorty-dialog br { - clear: left; -} -.shorty-dialog legend { - font-weight: bold; - margin: 0 0 0 5px; - padding: 0 0.5em 0 0.2em; -} -.shorty-dialog legend a { - padding: 0; -} -.shorty-dialog textarea { - width: 80%; height: 5em; - background: none repeat scroll 0 0 #F8F8F8; - color: #555555; - border: 1px solid #DDDDDD; - border-radius: 0.5em; - cursor: text; - vertical-align:baseline; - margin: 0.3em; -} -.shorty-dialog textarea:hover, -.shorty-dialog textarea:active { - background-color: #FFFFFF; - color: #333333; - opacity: 1; -} -.shorty-dialog input { - width: 80%; -} -.shorty-dialog a, -.shorty-dialog input, -.shorty-dialog select, -.shorty-dialog textarea, -.shorty-dialog button { - padding: 0.4em 0.2em; -} -.shorty-dialog input[readonly], -.shorty-dialog select[readonly], -.shorty-dialog textarea[readonly], -.shorty-dialog button[readonly] { - border: 0 none; -/* box-shadow: 0 0 0; */ - box-shadow: 0 0 0 #FFFFFF; - outline: none; - background: none; - background-color: #F7F7F7; - padding: 0.3em 0.3em; -} -.shorty-dialog button#confirm { - width: 12em; height: 2em; - border: 1px solid lightgray; - background-color: #EEEEEE; -} -.shorty-dialog button#confirm.sharp { - background-color: white; -} -.shorty-dialog button#confirm.sharp:hover { -/* border-color: green; */ - border: 1px solid gray; -} - -/* dialogs floating above other content ('standing alone') */ -.shorty-standalone { - width: 46em; - margin: -1px 1em 0; - padding: 0.5em; - background: none repeat scroll 0 0 #F7F7F7; -} -.shorty-standalone fieldset { - width: 45em; -} -/* dialogs related to elements ('embedded in the content') */ -.shorty-embedded { - left: 6em; - width: 34em; - margin: -1px 4em 0; - padding: 0.5em; - background: none repeat scroll 0 0 #EEEEEE; - position: absolute; -} -.shorty-embedded fieldset { -/* width: 32em; */ -} -.shorty-embedded a#source, -.shorty-embedded a#relay, -.shorty-embedded a#target { - display: inline-block; - width: 26em; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - vertical-align: middle; -} -.shorty-embedded a.shorty-clickable:before { - content:url("%appswebroot%/apps/shorty/img/actions/external.png"); - margin-right:0.3em; -} -.shorty-embedded select { - margin: 0 0 0.2em 1.0em; - padding: 0.2em 0.4em 0.2em 0.2em; - border: 0 none; - background-color: #F4F4F4; -} -.shorty-embedded img.shorty-usage { - opacity: 0.6; - margin: 1em 1.5em 0.2em; - padding: 0; -} -.shorty-embedded img.shorty-usage.disabled { - opacity: 0.2; -} -.shorty-embedded img.shorty-usage:not(.disabled):hover { - cursor: pointer; -} -.shorty-dialog label { - display: inline-block; - clear:none; - width: 5.5em; - text-align: left; - vertical-align: baseline; - padding: 0.6em 0.5em 0.4em 0.3em; - cursor: default; -} -.shorty-dialog span { - padding: 0.6em 0.5em 0.4em 0.3em; -} -.shorty-dialog span.label-line { - display: inline; - clear: none; - margin: 0; - padding: 0; -} -/* elements (rows) freshly added to the list, this calss might trigger visual effects like pulsation */ -.shorty-fresh { - display: none; -} -/* elements (rows) currently filtered out (toolbars column filter options) */ -.shorty-filtered { - display: none; -} -/* style of all icons (as opposed to all images) */ -.shorty-icon { - display: inline; - background: transparent; - vertical-align: middle; - padding: 1px; -} -/* dim entries with expired 'until' dates */ -.shorty-expired { - color: gray; -} -/* but keep embedded dialogs readable */ -.shorty-expired .shorty-dialog { - color: black; -} -.shorty-expired img { - opacity : 0.2; -} -.shorty-expired .shorty-dialog img { - opacity : 1; -} -.shorty-expired #until { - text-decoration: line-through; -} -/* some general style flavours */ -.shorty-prompt { - margin-left: 4px; -} -.shorty-value { - margin-right: 4px; -} -.shorty-single { - padding: 0.5em 1em; -} -.shorty-single:hover { - background-color: #EAEAEA; -} -.shorty-single:hover .shorty-actions { - display: block; -} -.shorty-id { - color: black; -} -.shorty-date { - width: 40%; -} -.shorty-notes { - color: blue; - text-decoration: none; -} -.shorty-source { - color: gray; -} -.shorty-target { - color: green; -} -.shorty-meta { - margin: 0.1em; -} -/* close buttons in dialogs, embedded or standalone */ -.shorty-close-button { - display:inline; - float:left; - margin:0 0.8em 0 0.3em; - padding:0; -} -.shorty-close-button img { - vertical-align: middle; - margin:0; - padding:0; -} -/* unlike elsewhere we underline clickable links in dialogs */ -.shorty-clickable { - white-space: nowrap; - text-decoration: underline; -} -.shorty-framed { - display:inline-block; - padding:1em; - background-color:white; - border:1px solid black; -} -/* keep long entries like urls from disrupting the compact appearance of the list */ -.ellipsis { - display: block; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - width: inherit; -} \ No newline at end of file diff --git a/apps/shorty/doc/CHANGELOG b/apps/shorty/doc/CHANGELOG deleted file mode 100644 index b1b09b50fb..0000000000 --- a/apps/shorty/doc/CHANGELOG +++ /dev/null @@ -1,59 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -Changelog: - -* Wed Jun 06 2012 Christian Reiner: version 0.2.2 -Added swallowing of accidential outputs during ajax requests. -This protects the replies JSON struction from being corrupted. -Additional server side log entries on level INFO -* Sat Jun 02 2012 Christian Reiner: version 0.2.1 -Fixed broken Shortlet -* Fri Jun 01 2012 Christian Reiner: version 0.2.0 -Support of ownCloud version 4 (app interface incompatible to prior versions) -Additional status 'private' for Shortys only accessible for the owner himself -Rudimentary SMS support for smart phones (more an assistance, can be disabled) -Additional QRCodes to publish Shorty source urls on the web (or elsewhere) -Data migration support as introduced by OC4 -Cleanup of Shortys upon user account deletion -* Sun May 28 2012 Christian Reiner: version 0.1.6 -Activation of Shorty sharing via SMS. -Enhanced backend descriptions. -* Sat Apr 28 2012 Christian Reiner: version 0.1.5 -Target url verification is less strict now, this way also more 'exotic' urls notations are accepted. -A few changes to the initilization scripts to prevent race conditions at startup. -Changed url specification in the Shortlet to prevent conflicts with a serverside suhosin protection. -* Fri Apr 27 2012 Christian Reiner: version 0.1.4 -Visualization of busy state in dialogs whilst fetch meta data from targets. -* Fri Apr 27 2012 Christian Reiner: version 0.1.3 -Prevented untimely submission of dialogs before having validated their contents. -* Fri Apr 27 2012 Christian Reiner: version 0.1.2 -Fixed race conditions during initialization. -* Thu Apr 26 2012 Christian Reiner: version 0.1.1 -Minor appearance corrections. -* Wed Apr 25 2012 Christian Reiner: version 0.1.0 -First official release. -* Tue Apr 24 2012 Christian Reiner: version 0.0.9 -Initial release. -Buggy, but some parts actually working. diff --git a/apps/shorty/doc/CONFIGURATION b/apps/shorty/doc/CONFIGURATION deleted file mode 100644 index 2a7dab60d1..0000000000 --- a/apps/shorty/doc/CONFIGURATION +++ /dev/null @@ -1,113 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -There are five aspects that can be configured: -1.) System wide "static backend" (optional) -2.) Selection of a backend per user (optional) -3.) Import of the "shortlet" into a web browser (optional) -4.) Access control inside each single "shorty" (implicit) -5.) Sending of Shortys as SMS - -1.) System wide "static backend" (optional) -(Requires adminisstrative rights) -This optional setting enables a 'static backend'. That is a backend generting -source urls based on a static base url, thus the name. That base url should be -chosen as short as possible, since this defines the total length of all links -to be posted and used. Most likely the definition of that url requires the -configuration of rewrite rules on the server side. So it is only an option for -experienced adminsitrators with access to the server configuration, be it -centralized or based on decentralized per-directory rules (".htaccess files"). -A basic example is packed in the .htaccess file (might be hidden in a directory -listing because of the leading dot (.) in the name). The rules must be -configured such that all requests to urls of the scheme -are mapped directly onto the web url of the shorty plugin -(http:////apps/shorty/). The is a string, 6-12 -characters long, hard to predict. It is guaranteed to be unique throughout the -system (though in a technically crude manner...). The perfect situation for the -definition of a meaningful static backend would be a domain with a very short -name and configuration access to something close to the web root. -A random example is my own domain "christian-reiner.info". Since that is not -exactly short I would love to use the additional domain "c-r.info" for the sole -purpose of a static backend. Unfortunately that domain has been reserved by a -domain grabber who asks thousands of Euros for it ! So that's no option. At -least you should try to find a setup where the web path of the ownCloud -application is not part of the base url. So that you get something like -http:///. -(Note that the shorty key is NOT part of the base url configuration). -You can easily test your setup any time by clicking on the example dynamically -visualized next to the configuration option. It runs a simple self-tests of the -setup in background. -There is no need that the base url must be served by the same http server that -serves the owncoud system. A static rewrite setup may well forward short source -urls to the shorty plugin inside a remote ownCloud installation. However, it is -a known issue that the internal validation of the setup won't work with such -scenario. - -2.) Selection of a backend per user (optional) -To generate the a source url that is part of every shorty the plugin uses a -backend. The configuration is done by using a preference option in the personal -preference section of the configuration. You can simply chose one of the -offered backends (combo box). Changing the backend does not affect any -previously generated shorties. Meaning they stay valid and usable and keep -their once defined source url. - -Different backends are implemented: -i.) "-none-" -As you have guessed this is something like a "dummy" backend without any -implemented logic. That means the source urls generated are exactly based on -the web url of the shorty plugin in your ownCloud system. This is not a very -clever setup, but it certainly works and keeps your data private. -ii.) "static backend" -If configured in the system administration a "static backend" is offered. For a -description see C-1. This backend typically offers shorter source urls, but its -setup required administrative rights on some http server system. -iii.) online services (url shorteners) -A few online services are offered as backends to generate short source urls. -Usage of some of those services requires you to open a free account at their -site. Detailed configuration requirements are displayed for the chosen backend. -If you don't care for details and just want short urls then have a try with the -tin.ny backend. No registration required, reliable service. But keep in mind -you depend on an external service as opposed to using a local static backend. - -3.) Import of the "shortlet" into a web browser (optional) -Shorty comes with a neat little "Shortlet" offered in the personal preferneces -section of ownCloud. It is a "button" you can import into your web browsers -bookmark toolbar or area by simple drag & drop. The Shortlet should work with -most modern browsers, though probably not all. Just have a try with it. - -4.) Access control inside each single "shorty" (implicit) -There are a few attributres you can configure freely inside each stored shorty: -- a title just shown inside the shorty plugin (serves recognition). -- a notes area, maybe you want to write down whom you send the shorty ? -- a status option that controls the usage of the shorty. - -5.) Sending of Shortys as SMS -Besides sending of Shortys as email message and copying a Shortys source url -to the clipboard a third action can be enabled inside the sharing dialog: -To send a Shortys source url as SMS. -However, the approach is extremely minimalistic, it relies on the client system -to correctly handle a 'sms url'. This is typically only given on a mobile -device, a smart phone. In addition, such url does not allow to specify a message -body, so the Shortys source url has to be copied and pasted manually. -The option is disabled by default. diff --git a/apps/shorty/doc/COPYRIGHT b/apps/shorty/doc/COPYRIGHT deleted file mode 100644 index 5e501826f2..0000000000 --- a/apps/shorty/doc/COPYRIGHT +++ /dev/null @@ -1,23 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** diff --git a/apps/shorty/doc/CREDITS b/apps/shorty/doc/CREDITS deleted file mode 100644 index 8f7a3dd037..0000000000 --- a/apps/shorty/doc/CREDITS +++ /dev/null @@ -1,32 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -The shorty plugin has been developed by: - -Christian Reiner, Hamburg, Germany -E-Mail: foss@christian-reiner.information - -Contributions: -I'd be more than happy to welcome all contributions to this little experiment. -Drop me a note, an idea, a patch, a good bottle of wine, anything ! diff --git a/apps/shorty/doc/INSTALLATION b/apps/shorty/doc/INSTALLATION deleted file mode 100644 index 0a98605376..0000000000 --- a/apps/shorty/doc/INSTALLATION +++ /dev/null @@ -1,53 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -This package is a plugin for the ownCloud web application ("ownCloud app"). - -There are two ways of installation: automatic and manual - -* Automatic installation: -You need login to your ownCloud using an account with administrative rights. -Open the 'Apps' section of the adminstration and select 'shorty', enable it. -Then go on below with the basic configuration steps. - -* Manual installation: -Download the package from here: -http://apps.owncloud.com/content/show.php/Shorty?content=150401 -Create a subfolder 'shorty' in the "apps" subfolder of your ownCloud web root. -Unpack the contents of the package into the new folder 'shorty'. -Now load ownCloud in your favorite web browser and login with an administrative -account. -Enable the plugin in the "Apps" section of the configuration ("*") inside -ownClouds web gui (requires admin rights). - -* Basic configuration steps for BOTH types of installation: -The "Admin" section of the configuration allows to configure a base url to -enable usage of the static backend (see USAGE). -The "Preferences" section of that configuration now offers two elements: -- a "Shortlet" to be dragged to the browsers bookmark area (see USAGE). -- a configuration of a backend to use to generate source urls (see USAGE). -The main part of the plugin can be accessed in the navigation menu as "Shorty". - -*** -Have fun ! diff --git a/apps/shorty/doc/ISSUES b/apps/shorty/doc/ISSUES deleted file mode 100644 index 083c464863..0000000000 --- a/apps/shorty/doc/ISSUES +++ /dev/null @@ -1,58 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -This is a short list of known issues: - -- The datepicker popup in the edit dialog fails to set the expiration date: -I have no idea what the problem is. Exactly the same object works flawlessly -in the dialog to create a new shorty. I can't see any difference, except in -the edit dialog the date is taken from the existing row entry (working fine). -Maybe there is some sort of magic spell to awake a datepicker after changing -its date value ? No idea... - -- Clicking on a source or relay url from within the sharing dialog updates the -clicks counter and access time correctly, but the shown list entry is not -updated accordingly. - -- Shorty does not work in the konqueror web browser -All appears to be working fine except for one annoying thing: -the standalone dialogs won't open ! (show, create and edit entries) -Therefore Shorty is currently more or less useless in this browser. - -- Shorty does not work in the rekonq web browser -The basic navigation elements (menu left) work, but the desktop stays empty. -Apparently no script is executed, an issue with the js document.ready event. - -- It appears there is an issue with setting opacity in the Safari browser: -The status filter in the lists toolbar shows an ugly black brick instead of a -dimmed icon overlay. Also some other style issues appear, but the plugin seems -to be completely usable. - -- When internally validating the setup of the base url used in the static -backend you get a false positive ("doesn't work") although things are fine, if -the mapping of base url to shorty plugin is done via a redirect. This is for -exaple the case if you implement the mapping on a remote server because you -want to use a different domain name for statically shortened urls. -The reason is that jqueries ajax calls won't handle redirects internally. A -wrapper will have to be implemented. diff --git a/apps/shorty/doc/README b/apps/shorty/doc/README deleted file mode 100644 index 4f590f30cd..0000000000 --- a/apps/shorty/doc/README +++ /dev/null @@ -1,42 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -This "shorty" package implements a plugin for the ownCloud web application. -Shorty offers a service to store, manage and use a collection of short links -pointing to ressources in the web. The features are a combination of a -centralized bookmarks collection, an url shortener and a basic access control. -The collection is presented as a list of "shorties". A shorty can be created -either manually in the list ("New shorty") or by using the "Shortlet". The -Shortlet is something like a Bookmarklet, a script based bookmark meant to be -stored inside the bookmark collection of a web browser. When clicked, the page -currently open in the browser will be added to the list of existing shorties. - -Each Shorty contains a source and a target url. The source url can be used to -be posted in forums, sent inside an email message or whatever. It is typically -shorter than the target url, a full blown web url. But that actually depends -on the target url and the backend used. The target url is the ressource -identified by the shorty. Basic access control is implemented to control the -access of shorties posted to forums or sent per email, but not on a per user or -per group base. Existing shorties can be blocked for usage, set to expire on a -certain date and obviously can be removed permanently again. diff --git a/apps/shorty/doc/ROADMAP b/apps/shorty/doc/ROADMAP deleted file mode 100644 index b18099c9af..0000000000 --- a/apps/shorty/doc/ROADMAP +++ /dev/null @@ -1,96 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -Future versions might implement additional features and services. Currently -planned are the following: - -* Ability to create Shortys directly from shared files inside ownCloud -Creating a Shorty based on the public url generated for shared files works like -charm. However it is not very convenient to do that manually. It would be great -to offer that option directly where file sharing is done, in that very dialog. -However I currently do not see any means to achieve that on ownCloud. There is -no feature offered to hook additional functionality into exsiting apps. -This means either the existing file sharing app has to be modified or such a -modifying core feature has to be implemented into the ownCLoud core. -Or maybe someone has got another idea ? - -* Integrated proxy function as an alternative to forwarding: -Currently all browser requests are forwarded to the final target url, provided -that the referenced shorty is still valid and accessible. This is a simple but -effective strategy. Offering a transparent proxy service as an alternative -would greatly enhance the privacy protection, since the final target url of a -referenced web ressource would never be handed out. - -* Better, more fine grained access control: -Currently the only means of access control, apart from defining or removing a -shorty are its "status". The status can block an otherwise valid shorty from -usage from outside ownCloud, it can restrict its access to authenticated users -or it can make an existing shorty freely accessible to the public. Other -ownCloud plugins allow to define individual access to content on per-user or -per-group rules. - -* Support of further backends: -Currently the usage of six url shortener services is implemented, besides the -two private or local ones. Unfortunately three of these had to be disabled due -to stability issues. Besides correcting the implementation for the disabled it -might make sense to support further backends, especially other types besides -online services. - -* Performance, stability and usability enhancements: -"Shorty" is my first web application using up to date web technologies. -Therefore the implementation certainly is far from the quality one could expect -from a serious and experienced web developer. One could also put this into more -constructive terms: there is definately much room for enhancements :-) - -* Translations of the shorty module itself (i18n/l10n): -Main development language is english (us), a german translation exists. I do -not feel fit enough in other languages to create a translation myself. So I -certainly welcome any assistance in that aspect. The effort consists of editing -one single file, take a look at the german example in file l10n/de.php. - -* Usage of svg icons instead of png graphics: -I created all icons in svg format. ownCloud implements a mechanism to use those -in browsers supporting svg directly. However I did not yet figure out how to -use that feature without adding too much scripting overhead. Is it possible -to reference icons the ownCloud way directly in a php based template, without -the need to explicit handling via javascript ? -I wish a better API documentation would exist for ownCloud ! - -* Localization for the date picker fields -Currently date inputs (expiration date) are not validated explicitly. -A number of formats work, are accepted correct, but there is no localization -of the input format to the users language. - -* Integrated help button -One thing I miss throughout the ownCloud application is a context sensitive -help, or a help button at all ! Originally I planned to integrate on into this -plugin. However I think that is more something that should be implemented as a -core feature of ownCloud. Maybe as a separate plugin (app). SOmehing like a -help framework with a documented api where other plugins (and core apps) can -attach help texts or documents to. Context sensivity would then simply mean to -update the reference in the help button for each action taken. - -Contributions: -I'd be more than happy to welcome all contributions to this little experiment. -Drop me a note, an idea, a patch, a good bottle of wine, anything ! diff --git a/apps/shorty/doc/STATUS b/apps/shorty/doc/STATUS deleted file mode 100644 index 0b85d14702..0000000000 --- a/apps/shorty/doc/STATUS +++ /dev/null @@ -1,42 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -The current status of this package is as follows: - -The initial release is definately buggy and contains annoying shortcomings. -It has been developed on a linux system using a firefox browser, so this is -most likely the best working combination. Basic usage test have been made with -a few other browsers. The package appears to be working in general though there -might be some minor differences in apeparance. - -Known shortcomings are: -- only very basic input validation is done. -- access control is not yet fine grained, no user or group support exists. -- markup, scripting and style definitions are the work of a web app newbie. - -So "sorry for any inconveniences" ! - -Contributions: -I'd be more than happy to welcome all contributions to this little experiment. -Drop me a note, an idea, a patch, a good bottle of wine, anything ! diff --git a/apps/shorty/doc/USAGE b/apps/shorty/doc/USAGE deleted file mode 100644 index a82f881992..0000000000 --- a/apps/shorty/doc/USAGE +++ /dev/null @@ -1,64 +0,0 @@ -***** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -***** - -=== Overview === -See file README. - -=== Installation === -See file INSTALLATION. - -=== Requirements === -ownCloud version 2 or newer on the server side. -A css3 capable and reasonably standards conform web browser. -A scripting capable bookmarks feature for the optional Shortlet thing. - -=== Usage === -This is only a very basic description. The plugin should be fairly intuitive to -use, just have a try with a few web urls. To get going I suggest that you -- chose a backend (see configuration below). -- import the shortlet into your preferred web browser (see configuration below). -- define a few shorties either manually ("New") or by using the shortlet. -All actions on existing shorties are accessed using the action icons shown to -the right of the shorty in the list. Daily uses is probably based on selection -the 'share' action and grabbing the visualized "source url". -By clicking on the header row of the list of shorties you can open (and close) -a "toolbox" offering options to sort, filter and reload the list. The sorting -you chose is stored in a persistant manner, not so any filters defined. You -cannot accidentially close the toolbox when there are still filters active. -You can remove (delete) existing shorties, but those shorties will only be -marked as deleted. This way you can 'undelete' them if required. Permanent -removal is done next time you access the shorty plugin. If you really want to -make sure the removal is done NOW then simply reload the list. This is done in -the "toolbox" of the list (click on the header row) by chosing the "reload" -icon on the left (or by a simple browser reload). - -=== PRIVACY === -Shorty allows you to stay more in control over links you post or send. It is up -to you to decide wether a once posted link should stay valid and usable or not. -However it is also very important to keep in mind that such form of control can -never replace any serious form of access control over the content published via -a published link. Shorty works as a short url resolver, meaning it forwards any -requesting web browser to the real address of the published content. This might -change when if future an integrated proxy function gets implemented, as opposed -to the current forwarding mechanism. diff --git a/apps/shorty/img/actions/down.png b/apps/shorty/img/actions/down.png deleted file mode 100644 index d2627e525eeeef58cbfb3b7e2056c39f89b3fb68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4ai_72CLoE;7yYO7_R5ShX0q0{z_=RqXTTg3w#3vO#SguPW!ycsVbxI2Ee on|1Y!ea|%B6*r&L`F~7!PLfmF-5b%;KqoMGy85}Sb4q9e00IkFApigX diff --git a/apps/shorty/img/actions/down.svg b/apps/shorty/img/actions/down.svg deleted file mode 100644 index b01642681c..0000000000 --- a/apps/shorty/img/actions/down.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/shorty/img/actions/external.png b/apps/shorty/img/actions/external.png deleted file mode 100644 index 5da1c41c45d4aa9d02f1136625e63cab26e00d16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 421 zcmV;W0b2fvP)i|_PwTQAA}Iq zG)*bb^Cn3WwG+F@k|d4B=WR1HRpEK`F&zvA}Az zLYk(hvMh&nUH>YIQpsJzaU7_siZBep7{hEf`#u~F@5kfuWw+ba7g3gF_`Z+HWCG9g z06^q<{+VUj&*e2^Y#7IJ)s@!kwbHijUw;f~+m@Zr=jWm*u2u>mPW}5I_Qh}{)k8Bb P00000NkvXXu0mjfi7c{{ diff --git a/apps/shorty/img/actions/external.svg b/apps/shorty/img/actions/external.svg deleted file mode 100644 index 32453b1ca2..0000000000 --- a/apps/shorty/img/actions/external.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/apps/shorty/img/actions/info.png b/apps/shorty/img/actions/info.png deleted file mode 100644 index 2febafa33e53dc9e2b6ea32abaa8ed4d459801f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^+(0bA!3HD`>}{| zgW!U_%O?XxI14-?i-Fp&gD|6$#_S59AbW|YuPgf<7GWMH1v$6L*+8L{o-U3d8t3<3 zSeVt6DANA%e#y}+iMYlMih8$M_OdqTo;8}Ld#@=xQFvPJy{3bufr8Dext)K6oqNE$ zuP&nI(!)9J_RnQL@oYRWTPW*?YvcO=X{O5algkdUSZ|-?UFRUq`zCfGTg1_Q%S(RD zxN?5RBlh(dqn`);u5i*0;_f;9?uW;dvY9sgA0^CFRz9$Pa&u|oDehN+`j1QB?|c%t m={?*0jAu{ewkek0>9yx&RrtQsu2~i6Xa-MLKbLh*2~7ZQ&~;$| diff --git a/apps/shorty/img/actions/info.svg b/apps/shorty/img/actions/info.svg deleted file mode 100644 index e92ab4fbf0..0000000000 --- a/apps/shorty/img/actions/info.svg +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/apps/shorty/img/actions/left.png b/apps/shorty/img/actions/left.png deleted file mode 100644 index e76cf4df2ed583874eea5fe14f75bed0a0d9b811..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 221 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4aT8xOA}1qA1Hgpz&xXY z|IL~EO_`1?daT+8A}I%#FW7TzpY|5sjk&$K{F*|sd+Yx9S_l8|zh&^yA{J;1gQu&X J%Q~loCIH|5N;Uuh diff --git a/apps/shorty/img/actions/left.svg b/apps/shorty/img/actions/left.svg deleted file mode 100644 index 670f0c3069..0000000000 --- a/apps/shorty/img/actions/left.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/shorty/img/actions/minus.png b/apps/shorty/img/actions/minus.png deleted file mode 100644 index 72ee0f69ff23c9ad4c44ddbc26bd27d33712efe3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 288 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m7>k44ofy`glX(f`FeQ1ryDWoOAL^Qxu9b@{39;6$)}n(=+q95|c|Z^Ye=Jb2IZwi@7wMH5HsQiZY8! zG86L@f>JZ{Qj0D|J8c5$5B79%4AD5B{O7!bgn=QCovRMVvz!0l2QIm1++viZQFZ=7 z)1noVz4EI1@A~opLG=S2@jG2H3zl&#nsKD%tWt<-gvh}u4+<_2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4Ay?z_9bxy^mY?xlS?|hRkMYeN)GJ#7H7K z*4_BRtJCwuR%LJ>@NwSEkSf5?(~#XC*`UN`A-znv;6m*`R)%K>v=eF=y2B>c3M`ne z&0oZ*);M8%SV#5(#=ZjvCd&Kf{Fk0v94xp~viL&n{9kkL-xbr#_?TR{0q7A1Pgg&e IbxsLQ0H!o?_W%F@ diff --git a/apps/shorty/img/actions/open.svg b/apps/shorty/img/actions/open.svg deleted file mode 100644 index 46e137d73f..0000000000 --- a/apps/shorty/img/actions/open.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/apps/shorty/img/actions/plus.png b/apps/shorty/img/actions/plus.png deleted file mode 100644 index f18d9c6c31ae9278df376035ef29bf51661b9d90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+0wn(&ce?|m7>k44ofy`glX(f`FeQ1ryD4nJ zFxG%D}l?a2B zxTF>*7iAWdWaj6=OxP-avJ)sR1d?_xN=*dGDTHL^rZN~A7#gj}Nxcb_bpgxf7gQEy zre~BeI6EsimXs7_CY6F!XOxr_Sn2C0gLRjsCgb7Z!h+AaSXBOt(|P09qK63x<6ljy->4;i=JDL%SOYkH#E$Y!kaES?G9<0 zV6R}ds5jz9u(yT zseKJN-k_PlC&BL4!0#acW6n(Z>l{XtlQxOYV61XrIDS>#Vf!N)W9Gk@M!Pb<@NxZtF#y#JDEF& zqC@woKHw@?A(}XQ*Mc;cJM2|oeRHlXfBof8?oazw`=lNS7D~TZQ_1acd6ml5&tFnWNN$d^$vdNf(a+%N>gTe~ HDWM4fnX@cN diff --git a/apps/shorty/img/actions/recycle.svg b/apps/shorty/img/actions/recycle.svg deleted file mode 100644 index 61ee3ac840..0000000000 --- a/apps/shorty/img/actions/recycle.svg +++ /dev/null @@ -1,93 +0,0 @@ - - - - - recycle - - - - image/svg+xml - - recycle - - 2012 - - - Christian Reiner - - - - - Copyright 2012: Christian Reiner - - - recycle - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/actions/reload.png b/apps/shorty/img/actions/reload.png deleted file mode 100644 index 06df1f194e08eb4fdc722721be89ddbb5357d48c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1083 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GXl47>@?{gt!8^&Fwu6EuCd`^>xkd zRdvl}RrST?HAQ9BHI1z$6}1&Ljp^A1IR&N3={fPq8HuS`2`QO{rL{2$sabhNshN2x z8M$#u>Dl=u|Ns978ij_MTDx1?dz;$2(NKMJM}12NkOW!^v>lFs+N&E{fL7NwwgE{r z1eB_*ZGs@6Q-QKTHjn{CaPiX0I-nQIs~dnW2O=OFh=78HrBy%#^cNgKMDmKtfhf1I z42~coS$V}k4`$>PX66Y$ zPAm!X14b+^z@?!m!OO(WWPJC^fqFjGJk^UT~NpmgoqpOr$k@1D6aiBBrI z{mr|2F)ND@>*QX>`Txq2{%&Cc(FuPyG1V?)WtuRN(c$A0N8{T+0(s~CJ8sX+WVUCW zu=>G=i%N^<-8pTfx#-ik)dqadEh|=bdI&Nu>bEulI*BpK+ucR-P2ScHAcwQSBeEDs zdw{Xq$!t3ytuM|Kd_aVXPE1VDtoSg!LkAS10xh?$+O=%k zy1Fdq#Tp*#BZ7-hnPsvQH#I0er2qP0vgCxj?;QX|b^2DN42FH~Aq*MjZ+{Ezopr03ji;1poj5 diff --git a/apps/shorty/img/actions/right.png b/apps/shorty/img/actions/right.png deleted file mode 100644 index a252a751554e142eb9dda6daecf529b41ffb0bed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4 - - - - - - - - diff --git a/apps/shorty/img/actions/shade.png b/apps/shorty/img/actions/shade.png deleted file mode 100644 index a49b9ad34c439039bf6abc7b315f3abb03c8c208..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 434 zcmV;j0ZsmiP)twyzCvChPY{IL zr_&<%06u`PAiH2CmJ4pDl_|x-CNH2)iajfb>kT5wz`$W<{{PJR`A=k~IwGRQH%zco z$_rfKG&67O`KAIk5z*liffH<%JSk%r5z$4&3r^Xf!8vBw%uGXxF{Wj<$;=mm4zs@j z2Z(0qR?ly7KXfy;u{BWNESNTMh{((zJux@%3s3lznZJAeBV<$5o_ig~_=t7<9O%yr z)&s`975DLsEcuMR0YM*L5nzNHJXQpcxW=eY&{&#eQmytKpRrce*6;-fRc(UB$kJiE zI4g}0mI@C=ROj7-)#9$N!y7&r7ff3lY5ER=sg;rbi;M1&07*qoM6N<$g1H&6@Bjb+ diff --git a/apps/shorty/img/actions/shade.svg b/apps/shorty/img/actions/shade.svg deleted file mode 100644 index 1823941c79..0000000000 --- a/apps/shorty/img/actions/shade.svg +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/apps/shorty/img/actions/up.png b/apps/shorty/img/actions/up.png deleted file mode 100644 index c878f84396c6a41574fe479fd7e69d92750e3ac4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4VB<|TA(oDN8@`XR{vGQ+)sc diff --git a/apps/shorty/img/actions/up.svg b/apps/shorty/img/actions/up.svg deleted file mode 100644 index 728243b3b5..0000000000 --- a/apps/shorty/img/actions/up.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/shorty/img/blank.png b/apps/shorty/img/blank.png deleted file mode 100644 index 9386bf3e17b85ac9191dda1a43be821bc3414865..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 219 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@ z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgfP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyW1 z1qvLz)q^Ae002N~R9JLFZ*6U5Zgcz zY-Mg_VR8y6Ln$CbXmV+DbZKF3AW~&%Ze?xc=hM{PyTFqe;{)J>q|(f80dJ|T7~@6YeJ$TFisG>i27`OR zbKnnf43rB^V|fWEYIz$tNUN$^2i}Dc9+_FSxG2CEYz-C=-Tk4YoixT6fXR3~{shqP z_W@c!7dTp&EwQ9&nx>zDVbX55hmy8tv)MjCr_%wr4IBXLz_})y*@mQvr0q1uNTXQ* zaiOh$u%DbieW2IttpOWlS^f$kyaDb4hro0Ne+6y;B&}9!=4l`0B$Kq) z;0uyo&*$@bk|c$s?dBBXf3yW4sXnRG5`IeRO8R1E_kklx$E(=guY?dNio!z(SIz8) tg%EncQ%Tns7FPTFb*9!l114s+`xp8|MQ|{P%WnVx002ovPDHLkV1kfZ6(j%v diff --git a/apps/shorty/img/drag_me.png b/apps/shorty/img/drag_me.png deleted file mode 100644 index 3ebac17d2d36f6ce4ce8d9357307a15a5107b000..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5189 zcmW+)2UOGU7fmU9T0r))RM~<|*@#72l&y?{h=TaTvZrhuK$${85M(&mP_u&eu0@0Jl@=X z-2)Ev{)Xu5%-|Nz?1}@=S$t6T{s6#x7TirCKAwO80PrlJk(aJN$X(3~3%@=>{2YZX zAg4Y-pqT05IDrt!VsRu%;^}LCOGw`B;_*jt8-w8|FFm(+d|hatnKJQD9-S&z4L!Y@ z${vDx^DykA6lVN@nJa`|2`NT*AytXw+J8Ky@5X4&&fQIg%pdOe-gDa-ySJ*gP~Sg& zxI)|!IuoyM_!!qcTxKn)D`qZ2?m;404S1tVXYb*E0PL{Z)CQmihhvBalpuSk17HvN z!MM&wCQ!tHgDeCq<4emKA0NLD7+1CLjC&6b4F$6OrCyQrWc;p_Yj%$bZ~Gr1Ou8ua zKSK4XG%=txEr}2i_J-V1oRXgh!xuAYUDjS_Sq6g)(p^hzOm}6Y6c4Cb!a)Hzs95fEs4` z7jQqr>a*#P&Ru~kgn@-Eh|)7Fy)LD2r|K*qsisCLk)rioTL`E$Dciv;@4&gw!dHLL z&@RA-1e8d$8RQoYS%-bupPdVDu|_tgPjWglMJtBu%`7l5FpQY`XbOMeq5z+h1YP2j zlSMrQK3Na~@i+uTfL)@_jA)JM0ai|>DHFEEiiU0BRzJ2w<;IEF;2Pq#EF8`mCwT=s zB}$qDTGLm~z~h0?^foQ$hLSTaJR~XjrcAUsI8W@+(NVeEx81lq(ct~>Rr}IR%3J|5 zB93YPF5tsTasvvWd%3PX!RGK%{U!;k_`MdVpO)siHIQ>Rd*aLX($k8ijsyFRU0T8B>ll_3_gNnbENBH znRSVif~@SODze|m9ZahWJ$VM&%tDF;
      lH!5say>5?0rd||DVa5mHRg9=t@JvW* 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 Hoge)VmsRiC diff --git a/apps/shorty/img/drag_me.svg b/apps/shorty/img/drag_me.svg deleted file mode 100644 index f1d44cdfb9..0000000000 --- a/apps/shorty/img/drag_me.svg +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - -Qt Svg Document -Generated with Qt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Drag - me ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/loading-bar.gif b/apps/shorty/img/loading-bar.gif deleted file mode 100644 index b02798a87ebd7cc1d19151adb4cf7cd8a3c661ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1190 zcmV;X1X=q>Nk%w1VcY-{0E7Sl|Ns90006$ezNV(8oSdAvxVW;ivdGBD*x1;_#KhFp z)ZE(9qEC?(Wvs*22QV zs;a8^`1qippq7@FEC2ui0Nel*000I4ARvxpX`X1Ru59bRa4gSsZQppV?|kq7z@TtQ z1PBI%q;kn@I-k&}bV{vSuh^`1IuNu3g@VKIC=WP}v?1;A6gKeq=FF~p9*MkujyCxJ z19%A=d4wE&e|~|3g@cE6Y=MN036E@mf|QScV+Mr+SBp zfNuhMWg7)vD+37z0umJ%zk7sW0vgK72nZVngwce%&DG7%dYRPL&A*|Ox&qwY27}+> z;|Si;3CQWi(ToKT>Dck@^Y7)~dHLh^?EGnBp9x#??C5hO z&7mjpj0{@S|gQ)AAwIA~~t1{#17XedAd1CE0bU_hWiLC^&g;>w*M zQh_zM0^rV_kU=EdY8Vvc-5b~MTDxoq6E@t;tzf-->#nW#m~dYSZkuUH40*0d4Tu{n zjx6Et-^z>fAOQmrK>o0SW9_viz;k_NR-S_p%GVY%6v9W_g88wfzy=vu#vwBvf~X;1 z3u2%QYY$pxp=KpQxL|vYeHh|i8Kn5vGA0IyqFc=H7-9z<$d%)Klzm882N8lsUWP3dcKRuoMVf7f=%9Emmt{4G#wk~s8a#=DfeQ$hnP~}BKqPz} zFz})^BKb(9sm_sFYIGichu*01-Q^Z|qpk{Tjkm@{D|D27CjpVUzRGJ`77<&duB(L> zs$x(n78|=K9*G^iKFT|7 zj3Qn*p^a-6xnX&y@%!tM<~E3~uXIVUVvQU4>hF&iGQ1{^90GjqkPqAYEeiw0^uREy z1*X_?BqwB=1|q{nU0h$zo7Zx`whUNh(=CcwgPaXVT|)257T%u+NN6sXin6SlX@Xfv z9F|9)Ml{Jx16(E4HmikX(#pw&!2wop#?T62gaoo<;0>oM(%Ef0T)zy=7^X-Rq?glb z!p6Uy!|GChApEJ?6veYD)Y0F9Dfb?{9bm&usYY~B({@21i zP@z88Lc*d@LH^<1zJW~s*GL||f!<75O))W)rca1(XqYc45M|-%8|WEAhyDp-WTIoG zlRP`)>@q|;Jm~arTEFdq72oW@_o-mEOneqMS-MdaUN?2!o2@C^BRlX)u2v$d=a~@zAX-)@q#0n`$QHVS4hYwa@9+L!eF7u zkjS7IPh>RGD?NiR2f>3C z2m0R+B7-9;qT`|0g{9#S;}b`F%P`1A1SbBmlXxTu6ZypODZV^Nq03 zH>C4}u;T+~{q3ft?BmnApRbS59bt*@AKz|vjZYA>SxQ$cDdI>H8yfv_deK+F*=Pnl|D|{deM6TkohM<382Kv94S-(^Y^vsx=L=Z`KI+CA| zA+`|U_T@z=1Pr@2T>)YQfqY%td&<^K;3FRjn5+aXN~KhKoqba;aZ%AH5i6EIWkX1-UTJI z=8mqr-S^<;v>q6-za;?pAWtcD#1Im2jTHoJ*Fz*ulOyhD7b8~SnCWF!a8)h{le@+$ zBPfk2^L$?Ybl(&G$>fb^#f$rU9}Gb}C7WB)HNybCAYu_tmnkFx85-BXs+D30!Ukw4r zrOCkYB-#KaI%xx7HZ;fqVs z=n{VR<4Bi zQUvX7VcTrOCpDrke5BX*s}k-8C8qlpws1VbY|V8sUvYgo@-pyr9Y+8E;|9%T6%1dd z8t>t`Clh0w&~Oh=wy=0~zinF`4>Ox;b%+vr%`IKm92YKohd+rt5R1y0AfPj)Ovw&H z1(IT1lY2i(6Yxt1gcb9to|j@_^2(s7kQgKwi-=ECa6^h`amXSxwQNElJc2TKFG!U! zKsHqYatV->D{ zU2KlRRTP?gugb_i^4!SgSu+4_?{s>O^Nd!@K2ryYTfJGVGn@YPt7gk*`0FP?5zyfk z!f7gqkw5laIB9K>Et}r1W*9HgciUuC;U~VA7<_6qVUtWKqf% zKf+bj>iflO_6jJ_?3YcQ%Y@VIW2-{)OK*|$r;<^EA$3G(U6%smTmofuiQ%0Mm2F$$ z93RGtj*%9=9NKGOHm%kQV;T`Ck31FJ z>yx~lF{SE58XSLJVr(@Z5_p|bDNs@&!?ZVhT*59+&F#KW3m-OeOq)UAozr3Ny}L-cC;_ML}z=3xq|{ zQtW5V_Wx?Aus>;&g5t75!`IE2-g-b8j)Er=D8+=?lW@nhQTk#Yc-({f5F(DBrF_HH zKv?=tMHBfKez{(kkE}{y?s;s}Km0uZ1&lut^^uDLzcZUUwDk@I4TLL)2c;w-q1WM| zY3T|!96SZA7zC8zD#yjMjsk|qd)zj{2^vO7CQ~jD%WnKho9>2taS)m+!GEACG_2|` zL}Ct1cOo-mv~QvWu>i-l&%>aSb(ruaRvAFMjApt>trF&`0h;0IyK;l-^}d~EeNYYf z%}OrLZ1UHyk9x8Is-_0^CzH4nR)X?Zs@G}%j|sLE^+cUxx}x0-OuEY{>-N;=gIZg9 zO=IGG&@Dl(X>LGURLfoH;*iQ56O)3~lRZOkw9qKkb!UGtV39?&t(To&1gS4k@w3EN zvm>&&!h~xEWB^7RO)ErcwdCirtl3pY?FS?nFn^xypxn~Z6OPsiO_(Wv3%{bl^E|I* zhI12sA3`o=YGIP3X!Fj9BW$u2;zIcaJ zZIs)^o)5V$!_?;?Nl!~+;yW%XMgF4T7nGelJvbm2Co8hbdb=CXWmE_~Q0Q4gWBbls zie<`g{WwYrQcH`Dy1{{sy{>0`97%d=33zn0;W)u5{Ck6@vi*!x_Yq%K#a^}Cn**vD z8!XEFW%SDO<$vp?Fy=p`;Lb=vo%Isf6S_Z%1`=%`=ue!%1F4#A3Rt-RV0{4*%gn+s zGG^D#Q(||6ZYI@${o&!~5-CF;=Yyan)wi=j`fRO7uco}m9o_IDAB{lQIUvB~VCiTi z6sxG7p<;^=$>qQypcrI9a4L^Sf@f?E4iG69%acx#Hy3O_bD6t&P2DkRb*^#U5T`c# z*g+U53!a0Rh>X3_YgC3PSp*DsE8I!Jcr3->l4Xb)CTsq!Ug%{-T)1J?E1C?hhu@e7 z{B(ZY)V%oTsgmpapYN!t^A8fC9HVZHLFVU~A$u1=BnjPHUeI&FVknxXK;G#}%}dRD z=S*q&0wH`y!m!0j&73Kepb)mSChySA?d|sj?)jM16}tktH_yh2jg7*ECFa1#Mnr+2 zLLBNLt>s+XQM})mY!_A!cr4*j%y(P$qw6l>!qiEkxLC9S9#(o9*REWdZ7IWGqnz`Ry4)cNZfHF1 z!-+CwRw|(2vdwf~2K%@7X#I=E{DX^^*;InZrWLXX4c$*igXR9gr58+}ZGpwa{DX^2 z5<`bxht!>_Rg%O@b!azkG)>Bu`0N8A@#uj;=Vqo~)z2}$)-(rvyA zacZx1Z3azcA)GbE9fy0+H;a+E{YW$|1_N)DGOae9^O9&D81w|m)0GBz8h!X1^ud$M(@8l#(dsRXJcij zOtMH-dQ#<}P0M)8c}=M7LP6;?s1Se~swrd}e+D%1Meht;?V06^9~gJpwi<6K9rU~2 zk=0l-3Gc>d6N9g(G3nJ4T*A7)aJ^(#3FhE@25dAqKh(bfO#*)wS`aC{*rvnPnC4fD ze^PHR?{hC8^{?^vD*kKvkI0R5c=Zjwqj}fM1bLLWRy$#x-`vtRi zxeScH#tAx`nUG*yx{6M&HUela1Prq%v(>=B$$^HoH8Q|I=9@+lz!Uy4-155NAtd<3rrQN}p_+eM1m@G&MW>gOll*?^tMs100@uV?-G~~lRnWgc3(w}tH+pAO@{kM18nD@a z&rcBeZleQ>ox?SChW`D8d39l0A7ov6s8aHW0e6{3RIWns1Sg+ zn>#x1P!*METnBXRWEh{$%-h;q!R zFFwqic7znw+OWT-PeFhKJ~Y2x{JyN;-q@RC0O-A%u~ZF~Iu8tKOSfbs)YFIe=H~Tu z=_Pd!G)uc=Qf6tQaTfafxZsg!M>^b${)*y=geF?63kCWlPu#o0K5cz?(Rb;d zfLn$cAn}6nee>KWE(X7*lk&6QuGWjLBxJJ*X6s$`cMa4WW42gBYQ#R@|Lm~4H4xRl zur!|OPe{0WH16p5%IL1=7{zZG?=(DIfBL+k~ zBL?2$0iXCus+G0*)_!H&IJKRLwD#pg-V{U7a12}ZSpD)?yMsV-GFgRUJk&ah$9eS# z*?-_>7RdppmTqF%`5@dQ_mkKnX&y+4czcl&+NO z$N<4%@}_wulLuco1 zFC<|!HdZunHMkVZvaqEQ)C)yiiE^pP{w>_x#)uB{Wx7`c)0J;N=VLHek*)HvU5 zrj8rf$XN2{j{_MwQ^oZ}*JQqMbTG3}y2I(ApEs{cPTgB=i`~icA^Xv`g)S$AF7eqN zK|;;MlmU~HsN^WeJwXL`EhXVvelVfml>ys1msBjrKvgI*IWecY;z6p=B0A(C1795b z!+)!&|DBtC5BU2@_7qv0p7tyE5XhEk5;o&Qo*pOQ5>_>B!6)Rc7<1>^-fcF1mZW8> zNAZIs0pN~3pNJFK?|F^(88>8%E~m(yWlb222O;bylE(^B zP?J_7Rpgc%f^REVC^VJH8$;XL{|wm@XG1o+P!B`~^p-(@3B!763+pBM&3k1Y=2>?6=J5qP5SqfvP+U_F0T3|^{a_#r~c9BhZVTv?;;9-37w)k~$~=I< zM4wZ+v`sw_hGkA@|HN(2*<6k6MldzobP@E(iGS|?3k__Op!a8ql#Hzv4Qltpvc2KA zzA;&@T6AV~8i{{*^6Bngw}u9UYx=BjoAX$d)K1>=Z;D`Y^2$E`_sP58ygE>3WQ|p#F*n^(X~Mm)DH-t$JiWY_M^pbs zOA*^YDFcx+aY*yG^o`pJVs2u3QDWY!HDZ!pGn_8LqYu&|{bU1GkKSIsdzLc5eM{UA z7-=9K6jv%Tls>0WgPo=><8=-g4~WVp0i+h=PS9p`l4QG!lc*zaf$9;tDZ! zQBKq;6@pfk34{<*viQ{0YZ_YH+S}AxI#`8^v_atjY7zuE*sl!c$gr6-f7 z*G5e@_;J)z;06WuRl1964u-4-IEwDi|}$>QFvS?1IxJ`v_%bajMYqTA=M@ z>4h?kxmMU;7#KWs2-2U<+CW?AM|Ls=n09Cno9Z|t@SJsuRbKC<$#x9xl4@a&dL6ax4IO+6-{9u7aG$u+%wh_ObNViNw=-f z$8~A`*$`K&e!>qB>#H^!fNoEW{mobNHJW~jA#`2`!X6g#jC0Yhtba8SZnPZro3Y8I zIriUr=CIgl4vl)FR^RaGwZ`Crv)*nG=)s1q(hE8p<=&ZB{Vlt1iymN)$}V^LKYnQu zfb1RwpXb#meGPJ%-16HM?mI8{jaB{Ql-Roy{WopxJURqq%Hj86T-@B(TjBzXq>Y5_ zuQv2C9sg7k{r~l^;J>g;1^X8UF>{OgzIA8I_#8ZDK2@AJd*b=Bh_miLxJst+Dhn|! zI9Vs(irPM3k=jnS#YKUW>%-rVUd=D=#8U+aLi z4{YuOw4f3B6b^9Ots5gYcQ{S-uJ0J z{B*F&arEWK32eynw{lK2K>ClwRMZpu+^R39S;ze_3*BFr zw>}b*h(n&j7-!tUDpD6->-PZGMu>-Oi(%W$ZV=ul1%qo-j}xGnWhXeZ4;-87Z*{>U zq3&xnYmFO0d1mbdfBbNMnJ}_oxrr@e93@zQWs;Unc@0(ZC8dMreEkk-Hso==1pg05tr>-_P jIV)*uw=h9G`A^AH|NpdfWjc|U(Jz9_ryC4FbSnP?;aSq6 diff --git a/apps/shorty/img/loading-led.gif b/apps/shorty/img/loading-led.gif deleted file mode 100644 index 78893c90606c099fef56559a739a6480ee43c601..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684 zcmZ?wbhEHb6ky^<%-8bE)%R}in9s-lM6i9!BZm__dd2Imak;LY=7h}zm4rlzqv`WjWXiNp z+;{)hp_OkgE$@B)X7B6W5&9Z)SR1VcJ0+N~X*2^`-JPiOxI=|gNs1?VNzx*XlhWt6 z^u9K_b$t5o15JCQKc4UwY&?7M@(y9YnTJBTwM3@*9TLE1lqt}tB^<7TA$7fvO_EeR zFTS$r7d~HF`P_OI@ABU#TI`ZGxc?IEKQpn|l0~X=^|kI@T62RGv6*B936E==BA&Sf zPTt{hDJdw__2ib=M^aoygMtcm6~W-kXGk>hcHt z(=*fQOgfv(<_q~^u~;gXZh%#8l*;AeLa|UN7` zoG#~>XAHzSIo842hwLB-25p08iy71i1}r+gUT@G_1}sL}sOnSosr!umv{t8;kt9ix zTD=Z37>?mmT&+>d6>^bSBlnRAP2}ubik>D7H<5EJ36H?eI!LW;%1Y)I1*(>Xn zD-;kw5zQqHl!fCA1_QWGuY+ntFEKkeI|r6-*c?2WbQ~-ZPo+||+P(Gl^<*-cNF?Hk z1Q38WL*Y<1o8A6>duwYe+(<-xexJ_|?pyw5x%zFjR;vL_z~XYdCZ{IXzFPx&^Yim7 zD=R>Q8Dy+h>y;~)0k6$&bGzNZ%F0-weeZ-9Xd8?MBTcI{8t9kqr&H4@pgr#O0^4Xb z3ZG5MDUzZ9CR_xx29$smT%yTj0w5+cj8Z8<0A2tq?hy-7RM>^eub%B`{4SgfCz1AN zo0i6czSxZ-k>+C}SnL}X^^GFP{(}u~LT1y4A-RVWV_kb5^Nu#Z{+861Eko)I6N^>ri?LY!Jx|UrbKyA7>ZUr3 zz4+(ni1u5nt6x}sx`z-FoV**i?n(?`q~^#D)taG;)k-+TYD=aZKu>Fw9}o2ON) z))&d*PtVTiza9>pCpMU;Kgv%jmUMS5f3KxZWdc0*uY~_2V#9Xt!Uvn%fUU4HfQdf`3vSR zTD)lK(xuB+EMK{D<h5aqXrD221`xHiwKX+2^-t&rBA_im6WTjEfT*UnrmDKCp|KH& zDyu3>%StOMD}bn^v?MP-FDEw#h=7c&?5xzZR3HK|($nJNq1BEEjUe*S(@(NUpcp&p(d9$ubd;bCDB;XpwjUmqVoUtd2z z{{Vl#0DquLA75W@UmqYlJR&?WC@?fE49EZ)5*-r_G!|%GLP7!%$Hm71O$!JNm^FLW zY#^8eL?AE$2qsRLJbChg0|(BWJ#*sZiNi+@14CfK#EHNV=m;U z)pj80=%{a~Z)t5kefsp=xpS+ltNZ%ShapJ_f`uh5YhO+Xq>YD0(`}Q?9H7;DZ zaO0+pRn^s*S($lxc^fvY2Zr?g`SXBrR8UZmnVAU;gtWA@+S=Nr?%M%!G&Mq#_t}ZoNHEqDOl3Wtx7p$6B2nRXx!QcMDz$e$>@1IG+{%<}* z!E+~ZXE#>}a1xHrWjF@3j|yGI$KnDaLSllVqJm<=(b?)TZ z)8}+7p?)rJkvKn z`~8cYyu52ylP{RRc=hVt%eSvz&NtY&`t*g4gEvwxEjjr%cv+e6Y`f%VD#6BV#odvc z)6UPd&aZpe6v>?)8D$u8TPMmS-|_P!PVZ@Y(fdwZ>pOTa@#v}0?(p@IyYrr&nyM`` zS7J`=we|7)8Ce>>RE3+fmG}3~evq(uxp?#T{`K?sXFE7JEXWQh@W_yGu5d{SDe=jP zsd4ft2}wy3VmNg`6-!cmAEyO$((8cYGCkm^>bP0l+XkKcIEPx diff --git a/apps/shorty/img/scheme/C.png b/apps/shorty/img/scheme/C.png deleted file mode 100644 index 61b873de73f85af0c3cc1cdffffddab21ee1fc68..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 978 zcmXAndrVVz6vr<#j9G$`X)=6}H2$%%KelCaFHKC4meH%dx3@3o`?ejG-a>Ef?QIJP z?WKfLphjw-GAOYt_5m%1Esfx2GUpbT2?$nngs`|6=C)+7EdH~^B|FW&IluEe=lp)> z=AKV}!vx-3%|FCP5TqIvi{!A^l-7$p@b$0nQ@~c{mNz#d*X|wp6+y}m5)x%ofD6Q8 zvG`2gQ3CTK=9(&MKG?P^ZWfn;V_)`_VxCh@8SCUq1e^k zK(`ZX;3m6n7m_&kO7>?tFR7yzUrUb*zU=m1M)vbg~1}zZi^g1JH zBuys0!2lIPModjlO@rbk0SaIR#HQoZW1#3*^ip(jadCZPy;!`zc5f}ekdH>AFe3=C zY;Ap?$)qPHCIDukP#75jIN<=t0r^lUw6eMa(E9v+fj|K8avbONd4WcFc=*n@cS1uU z7~E#F0i~s->o&>;^P0?NhGFLB=Uj}-Y_Vu{I{4M`iE&`7(Q36iEg;hA^)Q7}rBtd^ z_73}KWYpvF*eHr+-9Df1e;T+{syFCqns&Kd6h)z@(Go5c6^cZ{CXwsqU{&eGuyS01 zG(6opTS_cvnng&sqD~CSo^xW28$qh}msS}v6|aS2C5vKBl{@8!D{A(~o7-q89jBCP zR_Js%tTYQLf;fG&u+!;j6S!?ohV2%d>-4l!G+)TC7rrJC+8D~sQf68pw^Fo~dDws9 z0`&ZdicTqOAADrGg#;UKA5B`GJb5X3^pd>TPu(bc3(Lz_3;CPL&*nd0{;;k-q0+TJ-q_mQDQ;_Zx#|NO9UXuE@|)essm$z9Nag(|z}wImN4z$rE24sW-jr*nW2KSo_-4$@V{PQjZ$SzWAr= z>6`jO*LOwh%FpXdmHZDD)Hj%)<{x%EdV~Cw89YYZa@5u2$uG_Sz99I0?}5Lzm-p;_ suZLIh{5h}uhk@Y0z>cu->)UUg+=ujbY5(pC%{oee&?a1Tt8?Zpgh{z(OaB^ITG1ovd)-D99=R>CL{AT8QZdDQS8vLe>{!foZs(v&iUo! zp7Z(LQ#jUkkoPJNL6C!}NJzkWsJfnc3igI~UXa1T@epmtki~1S-$xK`6MkIY+CR`g zF)=YaJDbU5a=F}mex5C`3!pC-*g|1GpU<7mWwM#Mxw(nSiD)!BIyMSnHk&;?aym8~ zgIdtZp_2oH1MztLvv@q(9}P#sa0S*E>O0YU0y1EMV9@LH`U8G{Ai#JT+D$ttigHmd z+U0OMx-1rp)j~Q**!7+IPD3X+Mw3ycR;ko#aCCYdAtPjR88~W06iP)K zDiWb0WxG$Cc z8@s-KJsb`LtG-a^a`7^-0%#X6u0X5qZuippC3rHM-9|bbESpaz695O4{UU2H8mv}p zBoZ+g3>vK_nM~3&4FEM-t>5oYBoZdGS+0-+f#Flb@H8IA)7#fOI5-HXWpX(t!6dju zr_;gsp#OmbWD$y@AEP2LR0OC6LV-Xiblz@kuKrI9fyt1TolR>sFn!V{M22hL5JB*4 zw@B?lkmp{mE)Fs^T@T4x1{Jr~-r~Mi^Wxi$?+0FjR5K}8F#@;CWuX}e5yb7M1(e&{ z#rN3VJxq|_O?ho3%@gt(1aI;M_8!v1kVcwMSV-E^v!uFEf|@6&@FRJB*$ji5tVWCZ z?r+<-cYe1Z+$$^pe)@fGJF&g7TzUR*I%>BneHg6|TYWy?nR>kC>vVdFUCFV_=hEMH z@EZ79sai2Z;4*D{r}S`b9ZuQLQ4X3UT~}#0&gHQ_hVd!9{z_%X>t{JNN1yEPA2~j~ z(G>h~0}W|fI6sr+Bc*$j%^~G451Y%CD0j$n_u6z*_Z~jY sJ#^HAN(lFKmY&$ diff --git a/apps/shorty/img/scheme/E.png b/apps/shorty/img/scheme/E.png deleted file mode 100644 index d9c4e07001b8386d76ad57498ce7db65c34f839c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 988 zcmX9+ZA@Eb6uy)cX0cJHGmD$rEHT3$`?DX5`>}-4R(hemE$waThqS$AExk}~J7_6o zl$HW*VT`XLTg$!dTGB6QFeAgzIb&U-i315z66b`>EJkA>`bUj3#(1hvp7XxvoSgT( z?|Jf$DX<1U?=>ERAbeCJQo{aX*^X7hT6^vV6>Jqf%7%Jmb^G+s2*P<&A;rbPq2T<@ zd77bbv$vB=$y6$p$!2o7Tq>PfT3TXRmRV$=U@$N^abqHxOs3Q6{|lA@E6Xc@{7P;) zm(6A~nGAFozdjy`MsCG#0mI>NXgD-AJq3h|ph+Ye1rGQJ`mgl|hlYT@exIk;)9330 zx;<{nNjbV4KyW%bJFGSji{zYqtUiNQYw>5F_{d*<1tZOEU~j)6;;NX&7^(u(7}Y-EL{O zR4P5(d>D_%L5*-ETr3thw>IYh@6W|zv9a+n&>;{E1cGH**4Nhy_X-1kzkkr*>+JtR+1PCPp#(&P-e7>o!}!A^ z!;we?X3^=(z|}aeR;zH_+t(M3MqPlbE{dW+7ECVxPh?x$l{TeHi8i7V6etmjL_)DB zG5XHO<$vQ=Vk)HW$49nuU}^1;*Nv&y=PZ|C;z{x-3-l|Q2I z;uqPVg)$CaCYrCJq|vx|Tv4~4&)-k3E#FIjl+R=QT2}XD=h5E&?qltfogJ3@%1&2j z=dbqd!=sK$&LuWTc)fC`De(Kq*ulZUyLA;MG?tMv7yMsreHl9|KVQkyZYM6a|8oCX z&8y&Cn?Io__I~~Jt)`pjOn18fNq&C)D9D*y(R`Tr)b`b5&*9MXXW8Ikn1AX5#o-7( z`HWxteZg0A+VKa6_vc^FsyDb*RaFIUWF$=Vzk%%iWLV6tHr^Q2|c^b5F;QGGXj{^EoL@43A`R0J+*a{SZOAdc;B*KN5{(vYEns zp;#)?Wx7(S)atcGu%*RXyA zu%%wF*J?HBGo6}FBonzWa-euT9{V6Ro1O*1anK}@OoAq-CWG$>Bhe@*5DfSxeExtR zhYjrvup)*^|dQz`cDOGBf-aw9OMC?J3) znh_1Oh2sc<0N3iY&`mrfp3BeW!3rG%EDOa2pqDS?(_o*bXVYmQxwp5sy|cZwwbg31 zfF7WTC*s9ovE6Q8p|50f+0;x52!tcyaHInylgVssY$Puyr$SQ`mnHzkojX6IQmI%h z7L7*zem^x%jZtH_nzw4TYPn3iF1jd+0s?xHB=iIjgAZqS*o`J5X&}`a4O||cZ?)O7 z*(_-=KtU##$>egWOlB||H6tT{0vCx)CKEgvJ&ythGEL#=*fsVSV4*U5dE1p>z77izubi zhQ4Ks`&XMy`ufs0)#}Y=6KD37M%$ZrclWn{R<<`cOUzT7POEk0(H{qYKBlbJGYGr) z>EYpxLs2ewmU25+j)~VMf83>ZEbE1LtcSac(l;VqKY1Rs^0$d!n|#mjt$73U)HPkx z`0#q`w^SDSj%1Z0Po_VAJ=0LHlCSnOTnzTtD~#9;D`$<_cW>44?&-!82Kyh@k!J!& hSgeHq!}v#oMDS(gt*4ruUzi(22N24~c~=LB*ni=Vr(6I4 diff --git a/apps/shorty/img/scheme/G.png b/apps/shorty/img/scheme/G.png deleted file mode 100644 index d1d965d34cb522f770e4098ab05a52379cdbb623..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 995 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 F2>|ZfijDvP diff --git a/apps/shorty/img/scheme/K.png b/apps/shorty/img/scheme/K.png deleted file mode 100644 index 3d587ae4478b2048cfaa180d6299e10342001803..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 980 zcmX9+YfM{Z7(Oi$SPgN`#Y{I1E?H8O`ESl(vIJ-eJwneZy^oRP(WcpU0yx;e|*YBL?IcHLU zbvChHWFZLBgz~sTI1krWV;$`5*Pao7xLL$Hl4|&QmI5D5xpFxd{ihDx{^-kayh6%PqA2B1(a3`g#rx1 z4Z&b=A}}$(Fb_61J~liud};O)fcDcDDQY4Rfa=i2p~1mH+V6*C|3JUnG6zh@$H&*# z*Q?)DCxes8rR0N$4?v;`Kp^0wX^Nsi@ZH_r>6z)1e=?aI85x1kWVKoef`AtW3JRst z>-C1iVITtHh$UjNL;^yQBnf04PDf1#95^azFMTPP^T;c_`0+?h{5>a6`S zE+HmDT7P=fR}1uAom?bP{}K;^Ll<}oCxSfvTx~IsSo|0y8(b*AqhX(Uy#DB^H^OKB zfK-cFEO&A2Hk*NTL5LuBFUhgm-ETKLO?HQCp!tH;Z8VdtE*6{fYBR^=Fgsmlf@~HV z%%s6#y|p?GGY2TQO?>SBdEHH9xc%12wEo~gpFVkHPT0!$wz~0WD73d%3WZ8%T2i#$ zgOM7l%|rCOi_IJnv~DghZ#JbQTETgU1r v_n&Gw{t3<8rk*hTZI#L^{woCa<9xCKiFuTNKT)1LU6Tmyz_@Gey5WBT5dNi9 diff --git a/apps/shorty/img/scheme/L.png b/apps/shorty/img/scheme/L.png deleted file mode 100644 index 4e37b9f36457efdc4fc7f394a9d08eea278a6654..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 910 zcmX9-TTByK7@mRzDI%`$Ktz(pXhai3cH^#>sHwC-i=AQUeR`c%do%5{(kW^~%TQyf zN@8nD#nM7)=|$LeMcG6j%+?DpM2Lw(RMZ%=S>xrwM13*Q_*cLD=bZol{&ObteJAG( zj&;76XU7z zbS9n6X7l-c;c^N2LOz?zrZbsTDwRwoV;5uoe*e(W&_p_&%jKX8d#0wQrU8FW7YYS9 z2wymR?(AS_aOBbm#OdJaz^TCb@OcPkfbseLgP{;~`+R*~ua_AZ0P@7i6P{iV%n-DP zrks@BVTW)~4%<%yQV zlgk7`fuK_;SI8lN6rmy!hN2jT;ay#L7wi2-RN)M&N9 z03RQXj{*`ukW7pwM#F$ecsMpZH#Y~8Bauir5&>Nxb7ke}WOgzb42DWdL;VZ`4lgb) zfOWmcdwqUi@pcjPf+B$Hm}}=gbK&g1iWZTyMNi{DBYPm3`L!u|iT zxl|Yrb?}i;MUw!EDwlw8BS>{!X|RxZq5;TCT8Oq)J}YaisIPs${p%K>_SmFKn&)&l zOcV_zf;f*;JiF6#gyXh4d+3uKm)&ErQEU;rnYWF@v-a5Bw9PZxiRUVt-8 zLjFN%!^6X55ec;3*_1ZEdSy&+T7N;zWj(n!`Cl{|ee@_Ao!z`A#TdQq?Phte7sIIb z;Ch_t|7rZ!oGkf#$KY!h-SRG$r%3@8)Chhb6w|u^2vPsTmt$eHcTDKJ)`^~cx%jhpFh^Rs@JgDboJV*n!BI& XA-^glRx~Y9WzUTbTIltez z$?tQ21467cmwB9tAV@Bs#}&bPB;zj~fXF^`SPTopEGjKVZrnfd7(ud52?dgpPP)_M z@l5%rW&$(8*{39(+GP$(6UG^iSCq%~5R6cTy8TqG8Y zC1OaRgJLL#V~|u+^#7d_G|1oASY3VzF2vk%0TU-R_Z*5kQwnd+^a2(|($!7Zz@|np#a}Q#>96ZeH&-tyZgSP`ZX)qobo5f|#D3 z29gsK6DqaJ<#NetW!+c00YZC6yL-fKrYQIeQkhIFkyve3fDgFfj!vf&m;)KLTCE{8 zzyvs>IL0sIbGTei3D>rs+|E25N`#4#qTTJrOra_-G7@iSUjAMRU%Awlcte)l-}J<|N4q1f@E(U8g!PIB@>C$Z%3Jhbkwx|zCA#Q59u!yU(Sm+R@5_n+q<2+*z77jdKF-zx)Swm0#27|coBfBy2?#uMq{ zBf-pvsVuhgBcuHnN6(-s|17)i*49C`@}BO6^J>&obyj{ywON)Ep#Rvh?Eh%k{@niC z&NK7*FOcj9@4vw~9H9U7#9J0tbJ#z>exx9M^h93X)1$}pPj)@FB8_deA7A+A;9nU$ M{1S|Nqgd(q4_EfGApigX diff --git a/apps/shorty/img/scheme/N.png b/apps/shorty/img/scheme/N.png deleted file mode 100644 index 6c860f77347a8eeef65b3068f2e4444e5dc7da26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 996 zcmWlXdrVtZ9LH}V&0Ljea4|%uX%-(fZnDHJO0vXCi}a4(+tLSp(c6c%+}p=(18uh= zwxwh(ZjhD7N-4$O^*uJQfkkw~3<#UaNTmuU?iJ^E>TPe*NWp&iVa*=bW2- zKj(fS#oHS=FLMwCX+T9n8LThV#xwOW^A0>OhlSNAYi~sse%SjELF(R+iWP0aP%s{k zr)E=WCY{M<^7(wRSS+2ZMX^-O7xI~GmSLFL+1dD1JP-_wjEtPkWD11>?82G3xw-QY z7tWVTCAbJ*IC<)1bU2!rPJm8CPK1ZTr(>r+`}4@_0S8i*`62ASdmlY&MJ40-|gb%!I*UFd85+nN4bqTBFrKq9^n+xm>Q0LjoNP z$8ZS_iLy&6LPesZXqT!B1Whp}7ULL(j(p3 zFdDn{dgw?yrOBD(3`A-MC_%(xF|dN7{pzoLuAY5L#ytcL$ z4u{v**TFJLl0a{MVIG(O|D~lxzu!+%B)B%3jDQQ?1!!b*S-|LayNxE3R;SbIv@W-6 zd}17M1%tt<#8eMSDwGPjLeWF^M59qa2Oi;>CMG7pCXi99)nF5sNC<+k+wH&;J&KA@ zkVqgD3fhFfCH^tg{vMAEmm~ZKzgTO9xuac(46|PqL9yE{()1z7voF>L3rVJ$pt;L~ zVr{!_*S*4Se670L-wCZ2N}=`$Tu!Hj_CSdsu4A;o;qrdU?IT^i9zWOZ@b*wN2j}nv zZ*v7?FV*LvOf*+!p=e9*TOHjP+(wPS})frRlio% z=h%CyP8)7V?FU@;W*7ZaJ*Ua%@p=FL%X;X^6Upxf>o^HKb;y5x=Syn4SV^?}_#DsJ zVt<Aap3B8<*Ao$u-JQ5UlH$_9$)(TkM|wj-`(8J zyL*Y+E>yTHY|%F?_K{_JXlS0`vkV{phb*r$41f7(qWNT^fO6avf%gRBe ztymbaS_%|e+O_4gOf&X@{-O0BSlT(I>eMADCc3$)$)d!~nD}da?s?z$_xawv&wK9* zu%>eMvup%G%26Iy2rbo0azvr1W(`tGKbB=?{fMk=aNz z7L6z3$z(E}PA@DLkzPnAQ^|ND5sSrUXJaMIw<{q|s{RN(CR|^KlGP z5~+lT@_5atR3-&tIM%{%ZG|j`fsF}pT!3RZ4)v`N6W~(0OmJENT{5{$rB3vnM}sf?O0n|%VbvV z4hJX$!meLg@9yaa5jxBrAp6wxl+k27YcvMm4=yh+nJs3}0WNWTV%z{A2)#i+IyxE- zPZ9(HAFos?U45<#!3!WD9BN`>!s&8~C1RCY?e%(loxN}u9*?Ie3yyp$9gv-m&JLQI6z{e1gO(IHxzxQL(iJP({FJ9!El zf*d?r93{wfqymCvG|F!*yHolc>+lr$6~d=U1c*` zyXfAkPK*7liDKjIYR=159AlTsMw<*&m9X7JwRgSRc4`EA?xNg!am99<{u5-dA$vSd z?Cuir<3}chbtT^xF8>)Q&4T;R3Z7(+NP2c>n_8%{g0(IbMo^=sEIUS9b){^8O_ zN?KkWQ^eUMc(U$B)YPA7GXF e_ItgLhT5DjAmmAn@p@O#QWOep#JHIT{osFi(!V?a diff --git a/apps/shorty/img/scheme/P.png b/apps/shorty/img/scheme/P.png deleted file mode 100644 index e53d3ee9801d83988b2afd7f3ee590778b2b5b00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 950 zcmX9+ZA=?w9KQ}5W({g^I_755EHPq?`=WkWvbaiH=)v`RwAYtwY42KB+Qar*d)ER@ zM_(qT5Rx$i6`_Q)^bN)c9~z2tO5-Obqb?Dm(BJ!@-gw*l+7 zE0qc~!UyQ!Hvx%c;`-RwL?#2(*!5U68cigVkQ^Bu2}i;( zg9%}Q3vfQa56sW`*&)_F=mz`WanLl)&=5LZP77tBtQ0r{4!ho9Fpvhj!)~!sT3oBu z;ZQP~j2cvegV1C#5&Z;onJs49fXzWW zXoeZE+aUw_g~f$MKrXikUoJNTxHSWc-QT+p*xlW&)oOFuIiQwKrwfI`;n88KTmnH3 z4i4^pc`wssorxzBAmCnOFBXdxiiJj_0s4Uck>Lm^P_Nf{fxr93-O=bM@b!AV$yBmd z+XBJw+*$XsULfmqxfmxiJTd~ZPfkt-KMY!JHn^?TW(@=bAPx{GjU;I_8c5RP@xZ^J ztkx!9oz85rutP)r`hK(*1zD6Tl~S$hJIlP(d=`QpHz10~KMpnnS6`0`$w*((K=5=> zL-7dm%nQvSK^AfykZcuDt-AHmsq@nIH`4r9AxK?jNsFKi`2B89fDl0f!<^C=2w#)) z-atqgl?Q!c56j62S*P-KxzZbAd4Y9ua=n}7+#&U|L(|Z6h^pQrJHCIPsUxYbuP^3Z z$H%Vx#rBW&3dzI5$?X2g>`9?o-M@BOOt_-m(LqxL=N#SL>2^Z#&ea`pv$9>Nu3y>d zYU>m!ikc(sgu!M$Bvz$o9>A084Q#OA`urdG_FH5fTeV>!688MQ|L0ciyhMuq{nu+) z?(NU{UYd?CpCjs_U#m~v`faeW@UH)->Z(a0`S~ILxUsmy{Bc1(?{7U59N6~$a{OxF z*-NKVX{*mo_+Bh)<0d~++= N)CX1Ls*Nrt^&em?l&=5) diff --git a/apps/shorty/img/scheme/Q.png b/apps/shorty/img/scheme/Q.png deleted file mode 100644 index d07c42a76de45b0fe73b54792e006a6de5e6deff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1041 zcmWlXZA@BM7{@PltQ(D+X-#IjE+PG3ToyiWO|#AlM5u5<-jR1G$Ti*zg$pR_03E0x zZQZ(n!%GVYLM>?=7TcLNBTLL&YAa1=`jTyR#@Kb);y&1BANKa}-2XY}|2*fMo1EV{ zQ8C)x%s9+I5Tu#U<49m^X|&gxpzmP4DTRUNmUMR^*X|v8jv)K^Vu6es3{oSS*&VG@@847Ul}M+1X4clTN1-$wVL+h{xmETyAb|4rXD^{QUe?i1O7^ zsRSG053$ME_{8}1m(!rgSY-6m(F;=-K%tRPAP^Xzn1I={pPco7><^8MKyhez$m8`u z4+AJ;y;iHGQYknfL^7G&*w|QJ zUS3^YUAwz>?)*78JJ5!xR;vvfLEsUH#bWjQb$}lXg}gqm-|xSD`xfc(_=bE-OG|(h z;Mg(D;c!$IE5NqjZU-9q{A@Z+*)cm1uv)FzY&IMT8%;)&*=)90qOoY7Ml&`xHW{CU zv-D~D0Eo?IOHLOD-`@wd>$XvKnm#K763S#!(nqdZ1}jG$_VSP#tS1Qs1)hkd1PxO=ALd2GC_Zb z2g&PBp4yEd2M#qF4M|aLP~1=Qh1~r=?t7cw!qT-5uR!S-CR34Y2aa0_5>fBk60FQbF~E|YC{VQvyL5lo2{Bdjh-`x^q-v&-k4l(jvu7;DIA z*SAM==B+Jr?&!hKC7ra#`Ry;Zw|}_4y%*m*eJm3)+Y~l0O6UV8ZHmM}ac6a*bTfaQ zSuNknEl8R>GHSW*qCum4T7M*aSf;nuaSZRl9oX|^ neDq(amf76Q)TZhSPQiK;^7Xp*=J^*pHyXV7T$FRI%Q*T!h>*%> diff --git a/apps/shorty/img/scheme/R.png b/apps/shorty/img/scheme/R.png deleted file mode 100644 index 9b522d6c5a0dd2f64f6f597cf6bcff3ce3d19968..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983 zcmX9+eM}o=7{6|*8wH%%FcQWRvY3c5%VJ#2i2i}Jh2GY?)_#A`Pi^VZ_6q$t)&iw` z72L=`))j=K90#S9P13oNaLt^{FvblX3oHv8CK`e>>P$@BH2RlMR^aK2Pr2lvBXd*YB14qiaf)POACtNsN+_EpQJDsfM&Cz(vr zGxRJo%g(dubUKsCWIruNCYwnwrrG&ogt08)xcr8tJ+I4+mT>zm&KH>f-TuekH&C zXnT&G17~)2c5=B~d?*gudt$L@GzzAzt*wFcUESSWfxCJ03#x+(g+i&>6vuG`g9EGF zDtH2_TU@R}fn!;AWhFl`IpKD@L9)$mx7w`WEqoLg;p!jgPo+`@qY>U*Z!mOrc3vF4 z2olD}$HU>U!DvvaRVuX_ENb`r)f$abrE2%LYjryC1eeLcH)o3z3<0rjj|V-2N>EfN z5(&j3v$IND{Aq#;T#3{_*>)BS``IQDGR!|Ffuf{Mq7NWQ>5<~%AyafEkOzV&CO+`} zzN7pj$K;z;OF-2TDqT?M^Lia*5K08`b&x`jFZ5wez~%D?!!>Q5Pzyl{6oOje>or1` zp9lmA8(E`p5TwKJHqV#A%q}W=PgS|~f%O*B*KqqdYv0|qv&RpQE9!ZVzFOEzBoYe` z^7+K8bxh12X>@8RoHR!p8{>!N^(zdM%dRfuuiju8MR_fwSF24*qxOgUI;}d*uek4R zZ6%4%NVn`)SL^0}K_x{|4(jh`e?9M@s45;``kItJ6~6m`*m?&t>kAb*`pv+@r*&`r zd~fyxrKnAq>P#TO=|#)9Xcy_ZX0dCcQiYnKgN{jtD1_;$m! zqw-sUE$8X&J$}U>&;LBsR$3+y1WR8mDPMc`F7owL{l8P+{Ip)Q2o>X^#HMQNk#57x?TN+H(HgQ{1Ca8CnJ5COew{@Y%jJm34h@B4l4 z<(?+`Z4>vFq*Zr1JS@3;5ZfsTF$M8<43Tg;GHZB`wvqxCc-CdQDQ-SL2BU=o*iVgDvH98GOjx%#=!{ zt6yFP$)ll)_NCI&#>NIn9tnj6?Q$e4eh-D>zyL}QBFO7+SC$Bw zO&@_~wHL!%tDjZ9D}L+nKc{aA&}w$5bzT|gcH3DmlnBCIU}Y}OcfNkGkMnph)(^OR zy$-g9s%ell*30@ljzO=(%GRsw4%Y4o@EbqE%x{?dbM=v*yDe)-xMlr#*0#NE%N{>C zt&)n$-{*c!Z&tB$m(=D4gU7t;kuahwL?v>_I7voUi~rG^o2^f za+F;2{FP{=3i#Y7-8+9b#+O1>%MW`tZ+^VO?LFS3ANH0-;$y!{X3mbh%r;Xy5?#~t z0}U@$hyL9DprcMgSLN!y6^TE)aUycb&PYY(v;QG0Yl0wMc@f)cQf%%+QXgr5K=b#n OR9wPZ33;i-68;~hAdn6K diff --git a/apps/shorty/img/scheme/T.png b/apps/shorty/img/scheme/T.png deleted file mode 100644 index 1736eedc47b4890ef2bca05dd7085c576d2ee1ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 904 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1Jb#{oVet_=+h z)22_GGk4DX1@jjzUbJ-S(&a0buUxru>9VDZ7cXA0V8PsZbAbx#>g#%XdKN8Ov~1Zj zh=NtCR;>ntHLF*yTDfAyisj3f1GRT`ceQu4&zLy_h+5lPo0^;YC-ehRLt_Kbg!YaO zAgZaYsj9AOXlw)uR#sM)mX%giRsc~+X-QswUQTWf5CIuk*;%P+sX&yOl?f!{;^X5J z;(?6Bq{N8Gh{&i&AR{&|HYhkaI3yUz0E+nf`TF_$MMg)3hJ|`~dU$wwhJ}X#5m3;_ z*T=`t*VoU_FTmeFz#pj6$Jf`}*9XWAj|dM438NjLsBfqThC_XQ{egoA)~#DtQ(IeBURGXSzGdqcU}%?? zmI6JSnU%F{+0v;~r(|Sg0R5Pll$4a51Pss4&d!9ygsA9fpbLR<5g8Q~5*iW`8VYn| zV^bqA5P;tF^Y@2@m8X}dho`5ri;J_XOTtRqKcKiT3GxeOaCmkj4a7kowxipq6O;1TneV+34 z+0v)lOspYXTwL8<-d^3OPH}66G%`s|of>-8bZhC?tD#e;&T?R!%chW#lan}@~ diff --git a/apps/shorty/img/scheme/U.png b/apps/shorty/img/scheme/U.png deleted file mode 100644 index 320938cedf1a1b21dcb3f0a0ef3f096e5b03b38e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 977 zcmWksYfM^a7(PghN@u&YwlTXTW`D+(*z6Y5C0phM73$$|7m)(zs33>I0S^Z(;<%X# zI*dp*@N$T!SOjb5mO-*MX`-Q*HA^$hbd5h|)|qA5{ww0_|EJnv$1$=acL3q+Vr*PRCGQ$4;hYxgTY`d9*5J(k0&Pr6X8e%$gBRV zUY{2#B;#c$7v*p|Af1$xwA(FK3nXbLp_Z424!Vpi?N7Fap4E#b7d< z%s762$is+&DoD8VrMm!BN{NxDBeoH+Zb!kztKi z1F8d)fk-q0j#;hNXf&$PYQYCgE?22lG)<4uV>RfH{kY%u&h5?#23Zum9%S&I9!> zsTp8IE~nE%G0-B2Yn&1}T;7p3kIh9h{x-M6J4#Xltw1PxtxaU3Ne@F3RGZ2|QWpAj zEQ`X-kyQMlrgd)^-$9~Xl~-~@M@MIKDb@FHb@KlC<erS#``zZadP7IEh6=g|9kZvjNSjh|Ly&ay?@)obx-z2AG1Ha88~6@{AoqM<_Qj} ztK0a`xd(mej*EtlpLoKjcPAe_`|NGq=cdwyM{b_r_80u z3T!-lLT#l5r6pKIaG;x+)+H{+m^JA#P1a;}blIAwbLl@zm&N|EEb9*0$@lmBopW-| zxjCQQ5gFcE%Q?Y85Tq6r2?=;#t(-$uaPt~ok;B7s6RpiiY3Ge62*N%plaMVwzb}3* zKAW1onZB8s%Ve|J+(Is&&u8beb8~a)bUJk-1qGLeFO5%(XEK@j`T73~3WdTV*yoG+ zLVjUkA(zWR`{>wcI1;{|xDE=1LV-^M(O47&Ux5kXNCb4@;sx)J*XQ?x2EBt!A2TpG z0P-*%htpxR+d$y-e9~hwn?M!EV%AXZ0A?L<4YfCED` zT^bmxqjZ#B-=)<;Ue+#4&Ln5RW@i8tSS%J>TU%TIdOdczV$;*p+uPfK4mOQljsXGK zy;v;n{j?X2MnmCHDwQffD97XRFjyoq>>CCHR=c~q$z&496ida8Z#IC^u+P`m-?y|> zDl8U&jMwYEy?z_`GYmub&{nH87z!>gFFAXiLqkJux7$k70K{N4(libH`v>}`u1u*l z8rUKj3{Fl?xLhu^T1_fQQlXHOBmj(zL;w*m!KG4yAnbN~x2YR#Lq#Ym5DEn?LhZLZ ze^>q$4}r@O{{Ei15*Wp;LL^fCrU-%;dqtgY1UY=Pa#%=m_BbSKJSf&u^E11?x~~4& z)6*(QeMFNgkHBfSn;aep5yaW=5ZIhdH`i@-x;%s2UK?Yf9ULWxCpgU&SY5Q+LmM1i z!bCevt`D9!z63oFP~kc9_`UP`P2?YTpn2!|X)zxQ{ zJEcEv{IYshoA#ZfsOO)JTsgHSO_c9j4%Ia#&R#5!Csyv7rB&}q{On`y{hieNOTGUF zg8cFko_@vp=cBj9E7uxoei*a)*)N|_mb$*^IY>_Pm$zQyJ^b?63qKaCQa9y;nHk2s(CiBa*#y>M?>;kue6h$!fC(L&0b) zIv<};EF_kemQv}|GFWCgl};}umlhTl;_-NFE*1=hEMpe;q&tyFB$LVi%QBhFHL#Uy zP@hhxQ>hd*nQ%=wFFR*uX8;a|!+y!`@p=Go7j$qq9e`2usA&80hhz(r!9bZz6h$!>3uB=y78ElefwA}kKGxa_M<9SE z9i1JWU0ouvNGy@SjqM#BLZJ};Vy)P0I2?&aqS0t15&_=AV39BkzLsC}2mC(2Kby2!L%-h+dKa=GksyLR_>fh(8GRV;3WWr5b>W!MZ7e@X$vkIwmYOX*} z*7WzwaXoAiL^Fhw`!t3N^*WVCt2fpU^cj?Dyp~_vKz^s5tkSA=dbJdC4({%jSBZ7S!^giL&SM{Zw)VB9 zbio|A-knP9FK;KeX3q6Ki>`l5BCHvoo_M!2Ur>HudfOG6t*%)K=DriJ_xv5cad=O& zqaxOQdOxpz8vG%06W{pdtL`fwVYk)4-XVU;`(uB7Wb4n^hcR0fK63Qr=g&{j3)MBZ xp1o&Y zV?u9(WUyg7TPTbcxV5-7k+in4wi-2Ji&>_L8eL`<-QoxR)cC<@;zRc2_ul(FzdY}A z_xrtfiNJ@tB`-=41nEYVavki?b=H%|;Mv#ztR6N|NH;Wy-1_$AKMq7k|#M;feAXIDBm6erpxm;W>&Mz#?#%42_Or=t()oPF1*4Eb6 zAsXw@F9<@tUWXx<)0gM?x$7TX2c%M|Iq#ueG-aYpW)pqRWwYCKdcEGDw>j*< zU^s?raI?is8c8LpRH{(ph!Fs!8dIxr48w7p&}aw^bgD6I7*j(zLX8kwEgXRahFGi? z7;AUf9Zsj!W&@tk5{pZVOAv)6unV$6p^(jH^Y7=kx3@tx#OBuKwfwbgE(`K`p5NQs zJ8U0<8wUpmJ3Bi-#p3Z;ES65E+wFF#R9apxwpuOz51m9LyS0mA=*LH5cMSkw_$$%Yiut(qJG-urZNL zfNIKQf-3;+V9|ImXti0jIxVU~QI$$H3>cQlU=zlXayAP$J^_KosP4SJHuMSPp)a%5)|L?+2p+{}U#>TO)H^h>G zesgoObyt!8=dJmE^KZ|b3|Ky${_>mOr5h6dUZTss{=@!fUbY-B#iZpaA`r+{u3vnV zj~WY_Dy5ZjS!uP6f+;Axlq|gP04$6|AKXVAaWTtY9GWdzvYnosbN;_`&i~xp-!K1h z0`I776LYCK zW`Rkk)0s>r`=Df*Y$m;!W)>DwsZ=tVjNOg-{JuyeGS4uJi;FOYI}gEfxm+G1m(6Bj z7d|pEIT0QU-uCMQ)Ew%rP~5d_K=YE27|$90AMnklq#i4tpcFa>%{wMS=V3>gv?=6!4miOz!UPtgo++hDReeBYS&$ z%TJbpvOf?2^|rUS$0x?`&)whJ+6srmAijIh?eTh6R#rf_!b$;j0H#*bIy4koTYHwz z=Nx?wk|cqq$!rGV3^Q*u8PysM{GnE-1y#LXuS%_!%A``6Os0?zj|}(q_kkKEj=~bh zURy7ShIXP{9*^6`GyFZ#P;bF2-|1mHY_6|K zx=K~W;htx6t^MSHlQhw6v4x~9{eM_E0@&F{d0$FvfBee0frMJWKg*b3y{ci(PK)>m^k5BKjB_F0}(K-}KmEmynSaa!+QZ6sP6t`<{E*=OGs@|TO+dQM6v63wV( zI*CSM5Y1P!e(1GYt+pN-r79W^gXQfMMg3Wy)cw@lGJ1j7$UlAj_^H43-R2cGb(FOf zzvOv)a9)zZD#f?+!E*P-?w!Pi-uH>Mi@`!Ou|fX)?>~Q?`a=5w^SbFs#mkfD$_7(` y=hJD&(&ib?ufKnGyp~m0Q&Yz}ee%=b8xQi!CyJ}T4Sn8K5(RC;d5>C+q5lE1@P*d^ diff --git a/apps/shorty/img/scheme/Z.png b/apps/shorty/img/scheme/Z.png deleted file mode 100644 index 0d00ced9c149e1d641f2f274efb9eb88a753358c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 956 zcmX9+OH3PQ5MG;FCQhTKsT-wjA{lxihenZ*s`StZun{(R*Y-aAtnFPV1~2gg;q`-; zy>?YF6g4~|g0Ug4>G}Z(LWK~As&R5jDoTW)hoD4h6N>!eEMc*{?Yui zGvDsG9_u(G`&fn`$Qg}Vg@Zp^v-&!CHhuOU0ZtUeJKB)-rx%YAL@d>7$#$OS=kCsB z7qjq8iXuqzme&iP$?bN-*sy}#ZinGveN3kV zB_q*D5Woe!KA!={HJzHyu1=*&rEFJuuiN%({|AR-1k&>QS$FN=>grG-Daj=@98UGA zEkOi1{Xxw{$U^o4B&D1NZI`|fe$K2;Ec! zJ%N61K+)$7^{{@KRo0}utWbLT*&xRlHn8*~MED^9jO zYRu;wAGuzgn`sfHt9O38vsJBD-%S20x8(RXW7vrK9gbKl6W(srw+N-u&JSB#TWde% zOZbOPIRiyecEV=*U2ms^Q}TWGokZdFoKYd1mS6SMCI4Of?&%eUuU>xj`0wN6zy1s? z?jIf=`egF^^Vir{)yqT?&3w)tsJe3e-kXn_d-j%^BQM`dnhVdxl8fiBSa+ho90ApigX8FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H10%u7?K~y-6#gk1)RACf`pYOZhosx2lnaqU7pTU&!u8efXzg6Q; zKj4tLDJZgK5k;E|~MkqQNZ&aJ>u42{50(b0^?d%rf$X0|Rm zs{`+Q-otx1uh3evo07Yl22{Flyeb;H)xD^D5}ZU@$1k%1VWlQY*9{jyMU9Im$#TqCQk|>n45Ecc68iN0vqvo ztlPHj2f<+R^U2A{CiVOG)`39aNKe{WR#w)XR4V0NSy>iBNU61Eb#?WSQtGV7V^#s( zmSt(6XM215g7W!%qO0q%7#Qfswr$zgcHXnRyrMQXHkh8a0Vpp&X5{4L;Pd&M^rFtr zhns%CU#i^PgUMua{YEs}dO04Cxj=hK3CH{T`lH3gMI};7V`=Hvw}ytu0Pry_;PvL* z^!xqmqPO?y#PINFh2uCA=_3MRrBq`ia%$8xRo39(n@Y!VhJcYByxuU3=9-%DqzZ>a zv4w@j(CqA7jn=wS2;nHD%-Y&&GaRmZ<~WXbZEd|~Y;3$qYaIbF3_}KkL9?!|_LWE^ z68nI+Kq%u;9s&0N6L{jfZo3cyAw(J<0h&cROtx)%02gpA%W^Zsux;B5=pBw@S=Ju_ c@!!+<4>h6TMycH}Z2$lO07*qoM6N<$f - - - - - - - - - - diff --git a/apps/shorty/img/status/active.png b/apps/shorty/img/status/active.png deleted file mode 100644 index 51d013cd058037cb6872362c679b617dd9ccdc48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 485 zcmVq7ytkPhe5lRb*^P!xvWahho74svq? z?jVpr+GGI%8$m3@bqv^~nSDeQN7{@X5JZGNg-0gN;E|(NS zFbu;-h4+B$-k< zj73pU(=_&de_f<73~5;wyRQ4M+%ydh!(bf8*G0NL_`XlmG+9;EpPdcE;P?0Uz4mlW zQ4~=K!Np?1FbtVx8M7?ocDv<#KBuN>_s%yy$metJ`yNpgAx%@1WeMOqbH{Puc^(u+ bdHT$M`nmYhAK5#(00000NkvXXu0mjfch=50 diff --git a/apps/shorty/img/status/active.svg b/apps/shorty/img/status/active.svg deleted file mode 100644 index bb4c0573af..0000000000 --- a/apps/shorty/img/status/active.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/apps/shorty/img/status/bad.png b/apps/shorty/img/status/bad.png deleted file mode 100644 index 11627a21feedfad70dc1133a7af5be7bfc096851..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 795 zcmV+$1LXXPP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00FxI00FxJI_%@(00007bV*G`2iyW1 z1q=gchbdP8002U1R9JLFZ*6U5Zgc)XGVQwH&Wod3@auBhtz5oCMO-V#SR5;6}lfg@qaTv!x zKU*(M-FjK5fddH#%Qs>qj1FBo)@5EA4D$n%lG$z=Xt)55)uBVd}oPDDIahfxZ+7QpdccR zQ)Ur4@qq4NFgRk{_UgV@wr#HlgTWD?`;`CK$6jF2G|dUub+;>)CAoN97UFUFVp-z4 z?zU-~6Tl$QdjbITn5H>VtJSvFOC@=gNXToDPaqp0MUc5fLbggJsnu#*9;in|Xz@Df z42Q#k50=&OEEeN1m!rop2m)O|cO*hg95|9teeK6XCL9 z5L;T}AbFqf_wEv2UPdzv0wT19LX^wpI#53vBA`d3(WhT+yZHoU3S=djl;+-^9PaGM z#|KGyr;ryQ>$csDMx##w{dfy*rBbQxx3xKXUmp$N_pg2AumKl+?6<%H&}ta`Y;Sie zl}Z(Gk8&U)D5aLO*{pqMXz1$Z_&7JGEJ}}4G<+@eKc8S>WtD3WA2BmCV*|@a0X(+G zfUfIfKi1ZECnFJ=Hw;@5002ovPDHLkV1g{UQOf`T diff --git a/apps/shorty/img/status/good.png b/apps/shorty/img/status/good.png deleted file mode 100644 index 08ce0a4453a1670c51a38d4a423fd0afa47412d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 794 zcmV+#1LgdQP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00FxI00FxJI_%@(00007bV*G`2iyW1 z1q&tm%Q|fU002X2R9JLFZ*6U5ZgcT6Qd*=%;- z@AuCD-6BF=xf9iHx2yU`z1{W1#d2;LtUx2s25N^&>@0?B(uMv-Z@1g+Dxd=AfLtn- z%G*>Ma#jA0wh?Fn^-N{;)+$T)mk^6!Q*ESDsXUOY1mt6}Sk8IFDV%}!P(!<|(Olom zihYGvODo=2Uib~p>rRQqVmTmx{*5AXs3^*|<E zbIA<9fcIeDGZX3$$;7jX#bU9zCL+f*lUQzPFcOKZM~$d>-+INn=#}VBR3eecIxq;- z)l6aqq{U=1jRXP#-7t)dVHlY}AfTH}rV*g!f4@>|8x=)q0PX;NW$6=;5Rua=?`7Bd Y50#T;_-iD58jQ{`u diff --git a/apps/shorty/img/status/neutral.png b/apps/shorty/img/status/neutral.png deleted file mode 100644 index 5b2ad589cb9827c888e2a9b21c02fe3336eefa3b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 763 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L00FxI00FxJI_%@(00007bV*G`2iyW1 z1q(8H7{96j002g5R9JLFZ*6U5Zgc)XGVQwH&Wod3@aud`nu>b%9DM>^@R5;6}lfO?B zVHn3hFXBllR|*K#(1f8nCkll|$B_Ovv}zhPbY~6M{xWgpRP1 zp=2_t|NN92{P1*)%Pf)TgFBfU+@3Q?3_wyXv9&zL!ROpyGMUtYA>bI`RVo#)tGk~* zUFg!_+=V}V>d+w)<#(>TpGu|T0bVPhRw|WhJr_r%(F6hL22?l|9i$T)4d@vdl~Sox z18S`R-?r^))r&eE(Q62x&cjh7%tk;2h+gNT*W=i>T?PDOK-kD~KL6P2P2EKVqzP+} z%Dh{&Ktb~W^wd4_`Md>`j~B3IjCwpCzyED_yY9cbBEd_QhNXZ diff --git a/apps/shorty/img/status/strike.png b/apps/shorty/img/status/strike.png deleted file mode 100644 index d9a867fa004f79adc6ab14499fbc5a7ddba700b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 355 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 diff --git a/apps/shorty/img/usage/64/clipboard.png b/apps/shorty/img/usage/64/clipboard.png deleted file mode 100644 index 701bb6a7796d1b85a5d94866ad8458a01a0ce3d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3402 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 diff --git a/apps/shorty/img/usage/64/email.png b/apps/shorty/img/usage/64/email.png deleted file mode 100644 index cfa1f7678215206522db0fa434a7b869d1abd556..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4302 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 diff --git a/apps/shorty/img/usage/64/network.png b/apps/shorty/img/usage/64/network.png deleted file mode 100644 index fac47ac7b75c54d12b303dc2d028028173092b56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3451 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 d^T*Md$002ovPDHLkV1h$@Yvcd` diff --git a/apps/shorty/img/usage/64/qrcode.png b/apps/shorty/img/usage/64/qrcode.png deleted file mode 100644 index 207741888d309535d87ce477499f8094afd20333..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6373 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 N002ovPDHLkV1oZluK54} diff --git a/apps/shorty/img/usage/64/unlocked.png b/apps/shorty/img/usage/64/unlocked.png deleted file mode 100644 index 54501bbd11f17ae76f1ec980abc9673fa1feeda9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3115 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 FV1hpizit2k diff --git a/apps/shorty/img/usage/64/workstation.png b/apps/shorty/img/usage/64/workstation.png deleted file mode 100644 index 909098c9d8d25184321e5ecaedf30b00e0227237..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3218 zcmV;D3~lp?P)q7ytkaG)Y83RCt`#oN0_4$92blZ>DEvwWoKN zmv*__V<^Q0xg>Wrn{LkC|H^Q}R*8tuC z{yf{b#_tlpV^2*BxDd72A;O{jAxVi)s!2c8Q z`B*H*#!XvT*4tO#(|Qt#tZ;VUIDL|RFO0Y({3GzidL)D);0wS%#N%-`ZN7~gySgL! zS#{8hA`$GKKX;bBBR|I&1MnqPeYlqCngoc*CxGvY2pczTrn|eRX62!!N)eqSg3g{j z!~VS^?&ZCz`n_sJs}dk0!@yo3xn^h`>E$<7t+>CxpPrr`EXxYW5^0e2*$t{tRmo&B zy!P5_OiWBv&3fYaQC@xd5IF0MO{)50V4Xn(h)4_Y60p3tZ-AlUb%B*M+;9W;-+w=Y zgM+mJRe-8ZO0`t4z3J&`cI?=}3nMR7E&0-m2i#cUB(PRhC(3Qcs?_yw!1Csn7FG_f z#x^EUKmDmsvwCnf0)dKZQT>0^RBt(-4P%O$OeFY|?b}JG2QbFQHg<)7D+kxm*wh3t z06Y=|w1NN;*#vybo$drMwq2o17B6Pqx?xmJT|im|P>@RDNs9=f>ogWfF6G?lD8Qp4vR+kf zH@$q+`Z%yAkw}tG--NMks!1x9^7nDz@R7qj^2j4hPEO8v#`BAM{)G)2Ht@LzKIa>3 zQ>heo4L6>}$!UgjA{92rSitoE=#V#NsG2jaTef|B!<1tU)DyUsjV~p+0$v9*+b37Vr@lw6_a<2H?i7ZelUP7=N=W@6N`k@7}3Xr?G9fFNSab;TA>y4U#wC zyui|>ON(jcz6RNqSe(U6x;TGs6ySc~DJT#iA~yoR2e4@Il2AZYjW0cy%a$Ce8|Tk1 z;>+jq6bC}2?ik?8qQ#3`0`3%%E>%76wt$ZTvF7F$QmIrRqi*G{>&Ey&7-K>^5@gr^ zvtFR2l*V7Jm<1~BIv1%_1C5Q1WHK4S*}wdnOTb+K9i5#KK&WpPP@@>T`gAm72{Pfv z4LC7I6yiHN7m&%E0cRZenpN1h-vrRw+E!w-PUvcEyEqGo2u2NdP|K-szP8=!cgxZX z+z77ByB@9>#8!QWf{znu{$jg5Ac(CMG7v zp+LaR;6zm3K3uPH8a1UpuBG)tJ&Dxlt1_U4IY1BuW1C2Jlc^Lq>%vtQPGCSHnJo3; z5NxVZ#1oUNYW*=_#yI}3D9J>^y%?~7WdN3y@U(zB6OvLf^%!F+W`V$h zb?k-`r3hZt9|(o98@GxC^jJ7=Xb}k?P=HnhLdj&J=tzXUkJ_GANo}~H!FS(|Ks-RK zG<$biK(m`EFaQcNp>7~lvb1W|AiH+`IIzOduGKB3bar;q-PKii0M5O@P`HL&&t;

      `?Ll_8t0IDGdj`es4++ZkhggU>BPhY?d|QX zUcH*2NKZuY?A}$u5wPLuN8*88vghixOoj&^e2}rRF^tDIW7|w+rWn6^l}sj6tA+e3 z4%`N;HO6LodYa7C6uBZ90$QDnkv)58YHDKTs#O&&K|Sifax~0y*0SGTJ$3ptpZ&AX z^7`S|3$cJ9JAIw0sYxa$C&^~Bft#{r@~i-V3H(d79F}E~NF+%l6Ii7H!slLFTN}%l zFDKzkuMH?{N_n!Xa^=bujvYIOZQJDYIkLGN`CKjx;BxtM!D#`{hsiA>#N%-+%OW1P zu&g+q{l$uawWdT`6ginqVa1uZZR~u0W*abm*(f-1z!jkOC54q=~iZNQ)c{YXLcGV}Ws+>Q6J}M#CfcIIdnh}vb!0lm5ZQHhu#~ypk z-C+$as--c``#UIoCi2QFuW-j5caYDAK0Wums%G8x`;)Mx?!5EP$l$>bE(qvszyk~p z4$|A(8>Ps9L1|n337mnjt{dLb{@l59JoVI5w6?Z#_uY4sN~NMW;FH6L4|C+mkw|6w z`}pg@4Cj*7_t;v8)aB^NGSV9S;*jE#)}@Z^(EvUBIou*H3H{P=OU zZr$p6;So+mglC?4h7B7wM6L2^RecluZ-%}Z#lpzQND(~1bI(1;_3JY`*L>o{iOAr= z8T_KQnt~LudI|Uma6GJqjT<-8+}vEe-n@A;4Gj%7N>rCyZn=elfq}^7mMmGq?YD;- zyS?%n@IUTF@zt2B+9L9Iz<-9Z(%s$7?%lh2;)y3{Yir})d+&|vNKraEIyi9P0231x z2RLd(OhLs14Eb-z`G4#wt7!ZjP-VYfG@uXK+IG>Ul(5p0tDye^}7uws(z&&won9k zNchrw09080>oB-N6W}4@6TG(v#%sVIM#2;&bAf~nIA3?Z+hEJ}IL=fT4Nuep1rpkT z|9B68cJ*68%Z#whq>zV*-vM5I7l9uHw#*8{Yzh}huz*hjzy1vZKZf(QYJArI&(?s4 z2=^`1v-1Sn;H=|+e=dN#I-g&Ue-!5|-mSpQc1oO4{iirzkMB~|^K;{2N#=zBUj@!N z#37tLh7~vqtVKWv4lxQ`$N&EaypFRN`<2e} - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/arrow.svg b/apps/shorty/img/usage/arrow.svg deleted file mode 100644 index 94b2bf96ab..0000000000 --- a/apps/shorty/img/usage/arrow.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/clipboard.svg b/apps/shorty/img/usage/clipboard.svg deleted file mode 100644 index a470bdaae4..0000000000 --- a/apps/shorty/img/usage/clipboard.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/email.svg b/apps/shorty/img/usage/email.svg deleted file mode 100644 index 7283939e37..0000000000 --- a/apps/shorty/img/usage/email.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/globe.svg b/apps/shorty/img/usage/globe.svg deleted file mode 100644 index 018f161dbf..0000000000 --- a/apps/shorty/img/usage/globe.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/home.svg b/apps/shorty/img/usage/home.svg deleted file mode 100644 index 8c29644503..0000000000 --- a/apps/shorty/img/usage/home.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/info.svg b/apps/shorty/img/usage/info.svg deleted file mode 100644 index 31a3b6387e..0000000000 --- a/apps/shorty/img/usage/info.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/locked.svg b/apps/shorty/img/usage/locked.svg deleted file mode 100644 index 1691a9dfa4..0000000000 --- a/apps/shorty/img/usage/locked.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/network.svg b/apps/shorty/img/usage/network.svg deleted file mode 100644 index 1d3a025712..0000000000 --- a/apps/shorty/img/usage/network.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/qrcode.svg b/apps/shorty/img/usage/qrcode.svg deleted file mode 100644 index 83802042f7..0000000000 --- a/apps/shorty/img/usage/qrcode.svg +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/sms.svg b/apps/shorty/img/usage/sms.svg deleted file mode 100644 index 5d519df957..0000000000 --- a/apps/shorty/img/usage/sms.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/team.svg b/apps/shorty/img/usage/team.svg deleted file mode 100644 index c2d3c0075d..0000000000 --- a/apps/shorty/img/usage/team.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/unlocked.svg b/apps/shorty/img/usage/unlocked.svg deleted file mode 100644 index b993bd1458..0000000000 --- a/apps/shorty/img/usage/unlocked.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/img/usage/workstation.svg b/apps/shorty/img/usage/workstation.svg deleted file mode 100644 index 104d98f855..0000000000 --- a/apps/shorty/img/usage/workstation.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/shorty/index.php b/apps/shorty/index.php deleted file mode 100644 index 8c729bae14..0000000000 --- a/apps/shorty/index.php +++ /dev/null @@ -1,149 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file index.php - * This is the plugins central position - * All requests to the plugin are handled by this file. - * Exceptions: system settings, user preferences and relaying - * @access public - * @author Christian Reiner - */ - -OCP\App::setActiveNavigationEntry ( 'shorty_index' ); - -OCP\Util::addStyle ( 'shorty', 'shorty' ); - -OCP\Util::addScript ( 'shorty/3rdparty','jquery.tinysort.min' ); -OCP\Util::addScript ( 'shorty', 'shorty' ); -OCP\Util::addScript ( 'shorty', 'init' ); -if ( OC_Log::DEBUG==OC_Config::getValue( "loglevel", OC_Log::WARN ) ) - OCP\Util::addScript ( 'shorty', 'debug' ); - -// strategy: -// - first: decide which action is requested -// - second: execute that action with an optional argument provided - -// defaults: -$act = 'index'; -$arg = NULL; -// we try to guess what the request indicates: -// - a (shorty) id to be looked up in the database resulting in a forwarding to the stored target -// - a (target) url to be added as a new shorty -// - none of the two, so just a plain list of existing shortys -foreach ($_GET as $key=>$val) // in case there are unexpected, additional arguments like a timestamp added by some stupid proxy -{ - switch ($key) - { - // this is the OC4 argument used to identify the app called, we ignore it: - case 'app': - break; - // any recognizable argument key indicating a url to be added as new shorty ? - case 'url': - case 'uri': - case 'target': - case 'link': - // example: http://.../shorty/index.php?url=http%... - $act = 'acquire'; - $arg = OC_Shorty_Type::req_argument($key,OC_Shorty_Type::URL,FALSE); - break 2; // skip switch AND foreach - // no recognizable key but something else, hm... - // this _might_ be some unexcepted argument, or: - // it is an expected argument, but without recognizable key, so we try to guess by examining the content - // we restrict this 'guessing' to cases where only a single argument is specified - default: - if ( (1==sizeof($_GET)) // only one single request argument - &&( ! reset($_GET)) ) // no value, so maybe just an id - { - // use that source instead of $key, since $key contains replaced chars (php specific exceptions due to var name problems) - $raw = urldecode($_SERVER['QUERY_STRING']); - // now try to interpret its content - if (NULL!==($value=OC_Shorty_Type::normalize($raw,OC_Shorty_Type::URL,FALSE))) - { - // the query string is a url, acquire it as a new shorty - $act = 'acquire'; - $arg = $raw; - break 2; - } - else - { - // no pattern recognized, so we assume an ordinary index action - $act = 'index'; - break 2; - } - } // if - $act='index'; - break 2; - } // switch key -} // foreach key - -// next, execute the "act" whilst considering the 'arg' -switch ($act) -{ - case 'acquire': // add url as new shorty - // keep the url specified as referer, that is the one we want to store - $_SESSION['shorty-referrer'] = $arg; - OCP\Util::writeLog( 'shorty', sprintf("Detected an incoming Shortlet request for url '%s...'",substr($arg,0,80)), OC_Log::INFO ); - header ( sprintf('Location: %s', OCP\Util::linkTo('shorty','index.php')) ); - exit(); - // ===== - case 'index': // action 'index': list of shortys - default: - try - { - // is this a redirect from a call with a target url to be added ? - if ( isset($_SESSION['shorty-referrer']) ) - { - // this takes care of handling the url on the client side - OCP\Util::addScript ( 'shorty', 'add' ); - // add url taked from the session vars to anything contained in the query string - $_SERVER['QUERY_STRING'] = implode('&',array_merge(array('url'=>$_SESSION['shorty-referrer']),explode('&',$_SERVER['QUERY_STRING']))); - } - else - { - // simple desktop initialization, no special actions contained - OCP\Util::addScript ( 'shorty', 'list' ); - } - $tmpl = new OCP\Template( 'shorty', 'tmpl_index', 'user' ); - // the (remote) base url of the qrcode generator - $tmpl->assign ( 'qrcode-url', sprintf('%s?service=%s&url=',OCP\Util::linkToAbsolute("", "public.php"),'shorty_qrcode') ); - // available status (required for select filter in toolbox) - $shorty_status['']=sprintf('- %s -',OC_Shorty_L10n::t('all')); - foreach ( OC_Shorty_Type::$STATUS as $status ) - $shorty_status[$status] = OC_Shorty_L10n::t($status); - $tmpl->assign ( 'shorty-status', $shorty_status ); - // any referrer we want to hand over to the browser ? - if ( array_key_exists('shorty-referrer',$_SESSION) ) - $tmpl->assign ( 'shorty-referrer', $_SESSION['shorty-referrer'] ); - // is sending sms enabled in the personal preferences ? - $tmpl->assign ( 'sms-control', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','sms-control','disabled') ); - // clean up session var so that a browser reload does not trigger the same action again - unset ( $_SESSION['shorty-referrer'] ); - $tmpl->printPage(); - } catch ( OC_Shorty_Exception $e ) { OCP\JSON::error ( array ( 'message'=>$e->getTranslation(), 'data'=>$result ) ); } -} // switch - -?> diff --git a/apps/shorty/js/add.js b/apps/shorty/js/add.js deleted file mode 100644 index 7b120d888c..0000000000 --- a/apps/shorty/js/add.js +++ /dev/null @@ -1,51 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/add.js - * @brief Client side desktop initialization in case of a call with an url to add - * @author Christian Reiner - */ - -$(document).ready(function(){ - // initialize desktop - var dialog = $('#dialog-add'); - $.when( - Shorty.WUI.Controls.init() - ).pipe(function(){ - Shorty.WUI.List.build(); - }).done(function(){ - $.when( - Shorty.WUI.Dialog.toggle(dialog) - ).done(function(){ - // any referrer handed over from php (explicitly in markup) ? - var target=$('#controls').attr('data-referrer'); - $('#controls').removeAttr('data-referrer'); - dialog.find('#target').val(target); - dialog.find('#title').focus(); - Shorty.WUI.Meta.collect(dialog); - }) - }) -}); // document.ready diff --git a/apps/shorty/js/debug.js b/apps/shorty/js/debug.js deleted file mode 100644 index a45819152e..0000000000 --- a/apps/shorty/js/debug.js +++ /dev/null @@ -1,71 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied wpayloadanty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/debug.js - * @brief Client side debugging methods - * The inclusion of these definitions trigger additional debug outputs - * @author Christian Reiner - */ - -$(document).ready(function(){ - $.extend(Shorty,{ - Debug:{ - log: function(issue){ - switch (typeof(issue)){ - case 'string': - console.log(issue); - break; - default: - console.log(this.dump(issue)); - } // switch - }, // Shorty.Debuglog() - - dump: function(payload,level){ - var dumped_text = ""; - if(!level) level = 0; - // some padding given at the beginning of the line - var level_padding = ""; - for(var j=0;j \"" + value + "\"\n"; - } - } - } else { //Stings/Chars/Numbers etc. - dumped_text = "==>"+payload+"<==("+typeof(payload)+")"; - } - return dumped_text; - } // Shorty.Debug.dump() - } // Shorty.Debug - }); -}); diff --git a/apps/shorty/js/init.js b/apps/shorty/js/init.js deleted file mode 100644 index 3ab9fa7091..0000000000 --- a/apps/shorty/js/init.js +++ /dev/null @@ -1,92 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/init.js - * @brief Client side initialization of desktop actionss - * @author Christian Reiner - */ - -$(document).ready(function(){ - // make notification closeable - $('#content #notification').bind('click',Shorty.WUI.Notification.hide); - // button to open the 'add' dialog - $('#controls #add').bind('click',function(){Shorty.WUI.Dialog.toggle($('#dialog-add'))}); - // close button in dialogs - $('.shorty-dialog #close').bind('click',function(){Shorty.WUI.Dialog.hide($(this).parents('form').eq(0));}); - // status selection in embedded share dialog - $('.shorty-embedded#dialog-share #status').bind('change',function(){ - Shorty.Action.Url.status($(this).siblings('#id').val(),$(this).val()); - }); - // button to open the tools header row in the list - $('#list #titlebar').bind('click',Shorty.WUI.List.Toolbar.toggle); - // button to reload the list - $('#list #toolbar').find('#reload').bind('click',Shorty.WUI.List.build); - // sort buttons - $('#list #toolbar').find('shorty-sorter').bind('click',Shorty.WUI.List.sort); - // add date picker options - $.datepicker.setDefaults({ - dateFormat :'yy-mm-dd', - appendText: "(yyyy-mm-dd)", - changeMonth: true, - changeYear: true, - showOtherMonths: true, - selectOtherMonths: true, - showOn: 'button', - buttonImage: $('#controls').find('#until').eq(0).attr('icon'), - buttonImageOnly: true - }); - $('#controls #until:not([readonly])').datepicker(); - // bind usage to the usage icons - $('#dialog-share img.shorty-usage:not(.disabled)').live('click',function(e){Shorty.WUI.Entry.send(e,$(this));}); - // bind actions to the actions icons - $('#list tbody .shorty-actions a').live('click',function(e){Shorty.WUI.Entry.click(e,$(this));}); - // bind highlighting to clicks on a row, except for the action icons - $('#list tbody tr td:not(#actions)').live('click',function(){ - Shorty.WUI.List.highlight($(this).parents('tr')); - Shorty.WUI.Dialog.hide($('.shorty-embedded').eq(0)); - }); - // pretty select boxes where applicable (class controlled) - $('.chosen').chosen(); - // title & target filter reaction - $('#list thead tr#toolbar').find('th#target,th#title').find('#filter').bind('keyup',function(){ - Shorty.WUI.List.filter( - $($(this).context.parentElement.parentElement).attr('id'), - $(this).val() - ); - }); - // status filter reaction - $('#list thead tr#toolbar th#status select').change(function(){ - Shorty.WUI.List.filter( - $(this).parents('th').attr('id'), - $(this).find(':selected').val() - ); - }); - // column sorting reaction - $('#list thead tr#toolbar div img.shorty-sorter').bind('click',function(){ - Shorty.WUI.List.sort($(this).attr('data-sort-code')); - }); -}); // document.ready - diff --git a/apps/shorty/js/list.js b/apps/shorty/js/list.js deleted file mode 100644 index 89f319e2e3..0000000000 --- a/apps/shorty/js/list.js +++ /dev/null @@ -1,39 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/list.js - * @brief Client side desktop initialization for normal calls of the plugin - * @author Christian Reiner - */ - -$(document).ready(function(){ - // initialize desktop - $.when( - Shorty.WUI.Controls.init() - ).then(function(){ - Shorty.WUI.List.build(); - }); -}); // document.ready diff --git a/apps/shorty/js/preferences.js b/apps/shorty/js/preferences.js deleted file mode 100644 index 4cda3ab37a..0000000000 --- a/apps/shorty/js/preferences.js +++ /dev/null @@ -1,69 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/preferences.js - * @brief Client side activity initialization for the user preferences dialog - * @author Christian Reiner - */ - -$(document).ready(function(){ - // backend preferences, activate hints for currently selected backend - var type=$('#shorty #backend-type').val()||''; - if (type.length){ - $('#shorty #backend-'+type).show(); - } - // backend 'static': initialize example that depends on backend-base system setting - if ($('#shorty #backend-static #backend-static-base').val().length) - $('#shorty #backend-static #example').text($('#shorty #backend-static #backend-static-base').val()+''); - // backend 'static': offer a clickable example link to verify the correct setup - $('#shorty #backend-static #example').bind('click',function(event){ - event.preventDefault(); - Shorty.Action.Setting.verify(); - }); - // react with a matching explanation and example url when backend type is chosen - $('.chosen').chosen(); - $('#shorty #backend-type').change( - function(){ - var type=$('#shorty #backend-type').val(); - $('#shorty .backend-supplement').hide(); - if (type.length){ - $('#shorty .backend-supplement').filter('#backend-'+type).fadeIn('slow'); - // save preference - Shorty.Action.Preference.set($('#shorty #backend-type').serialize()); - return false; - } - } - ); - // safe preferences - $('#shorty .backend-supplement').focusout(function(){ - // save preference - Shorty.Action.Preference.set($(this).find('input').serialize()); - }); - // safe sms-control - $('#shorty #sms-control').change(function(){ - Shorty.Action.Preference.set($('#shorty #sms-control').serialize()); - }); -}); diff --git a/apps/shorty/js/settings.js b/apps/shorty/js/settings.js deleted file mode 100644 index 254ab4f0c1..0000000000 --- a/apps/shorty/js/settings.js +++ /dev/null @@ -1,53 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/settings.js - * @brief Client side activity initialization for the system settings dialog - * @author Christian Reiner - */ - -$(document).ready(function(){ - // initialize example that depends on backend-base - if ($('#shorty #backend-static-base').val().length) - $('#shorty #backend-static #example').text($('#shorty #backend-static-base').val()+''); - // modify example upon input of a base - $('#shorty #backend-static-base').bind('input',function(){ - $('#shorty #backend-static #example').text($('#shorty #backend-static-base').val()+''); - }); - // backend 'static': offer a clickable example link to verify the correct setup - $('#shorty #backend-static #example').bind('click',function(event){ - event.preventDefault(); - Shorty.Action.Setting.verify(); - }); - // store setting - $('#shorty #backend-static-base').focusout(function(){ - // modify example - $('#shorty #backend-static #example').text($('#shorty #backend-static-base').val()+''); - // save setting - Shorty.Action.Setting.set($('#shorty #backend-static-base').serialize()); - return false; - }); -}); diff --git a/apps/shorty/js/shorty.js b/apps/shorty/js/shorty.js deleted file mode 100644 index 688c3e6e15..0000000000 --- a/apps/shorty/js/shorty.js +++ /dev/null @@ -1,1489 +0,0 @@ -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file js/shorty.js - * @brief Client side activity library - * @author Christian Reiner - */ - -// max()-selector -// usage: var maxWidth = $("a").max(function() {return $(this).width(); }); -$.fn.max = function(selector) { - return Math.max.apply(null, this.map(function(index, el) { return selector.apply(el); }).get() ); -} -// min()-selector -// usage: var minWidth = $("a").min(function() {return $(this).width(); }); -$.fn.min = function(selector) { - return Math.min.apply(null, this.map(function(index, el) { return selector.apply(el); }).get() ); -} - -/** - * @class Shorty - * @brief Central activity library for the client side - * @author Christian Reiner - */ -Shorty = -{ - // ===== Shorty.WUI ===== - WUI: - { - // ===== Shorty.WUI.Controls ===== - Controls: - { - // ===== Shorty.WUI.Controls.init ===== - init: function(){ - if (Shorty.Debug) Shorty.Debug.log("init controls"); - var dfd = new $.Deferred(); - $.when( - Shorty.WUI.Controls.toggle(), - Shorty.WUI.Sums.fill() - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Controls.init - // ===== Shorty.WUI.Controls.toggle ===== - toggle: function(){ - if (Shorty.Debug) Shorty.Debug.log("toggle controls"); - var dfd = new $.Deferred(); - Shorty.WUI.Notification.hide(); - // show or hide dialog - var controls = $('#controls'); - if ( ! controls.is(':visible')){ - $.when( - $.when( - controls.slideDown('slow') - ).done(Shorty.WUI.Sums.fill) - ).done(dfd.resolve) - }else{ - $.when( - controls.slideUp('fast') - ).done(dfd.resolve) - } - return dfd.promise(); - }, // Shorty.WUI.Controls.toggle - }, // Shorty.WUI.Controls - // ===== Shorty.WUI.Desktop ===== - Desktop: - { - // ===== Shorty.WUI.Desktop.show ===== - show: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("show desktop"); - duration = duration || 'slow'; - var dfd = new $.Deferred(); - $.when($('#desktop').fadeTo(duration,1.0)).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Desktop.show - // ===== Shorty.WUI.Desktop.hide ===== - hide: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("hide desktop"); - duration = duration || 'slow'; - var dfd = new $.Deferred(); - $.when($('#desktop').fadeTo(duration,0.3)).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Desktop.hide - }, // Shorty.WUI.Desktop - // ===== Shorty.WUI.Dialog ===== - Dialog: - { - // ===== Shorty.WUI.Dialog.execute ===== - execute: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("execute dialog "+dialog.attr('id')); - var dfd = new $.Deferred(); - switch ( dialog.attr('id') ){ - case 'dialog-add': - $.when( - Shorty.WUI.Notification.hide(), - Shorty.Action.Url.add() - ).done(dfd.resolve) - break; - case 'dialog-edit': - $.when( - Shorty.WUI.Notification.hide(), - Shorty.Action.Url.edit() - ).done(dfd.resolve) - break; - case 'dialog-del': - $.when( - Shorty.WUI.Notification.hide(), - Shorty.Action.Url.del() - ).done(dfd.resolve) - break; - default: - dfd.resolve(); - } // switch - return dfd.promise(); - }, // Shorty.WUI.Dialog.execute - // ===== Shorty.WUI.Dialog.hide ===== - hide: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("hide dialog "+dialog.attr('id')); - var duration = 'slow'; - var dfd = new $.Deferred(); - if (!dialog.is(':visible')) - dfd.resolve(); - else{ - $.when( - dialog.slideUp(duration) - ).pipe(function(){ - switch ( dialog.attr('id') ){ - case 'dialog-add': - dialog.find('#confirm').unbind('click'); - dialog.find('#target').unbind('focusout'); - break; - default: - } // switch - }).pipe(function(){ - if (dialog.hasClass('shorty-standalone')) - Shorty.WUI.Desktop.show(); - }).done(dfd.resolve) - } - return dfd.promise(); - }, // Shorty.WUI.Dialog.hide - // ===== Shorty.WUI.Dialog.reset ===== - reset: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("reset dialog "+dialog.attr('id')); - var dfd = new $.Deferred(); - if (dialog){ - // reset dialog fields - $.when( - $.each(dialog.find('#status'),function(){ - if($(this).is('[data]')) - $(this).val($(this).attr('data')); - else $(this).val(''); - }), - $.each(dialog.find('input,textarea'),function(){ - if($(this).is('[data]')) - $(this).val($(this).attr('data')).attr('placeholder',$(this).attr('data')); - else $(this).val('').attr('placeholder',''); - }), - $.each(dialog.find('.shorty-value'),function(){ - if($(this).is('[data]')) - $(this).text($(this).attr('data')); - else $(this).text(''); - }), - $.each(dialog.find('.shorty-icon'), function(){ - if($(this).is('[data]')) - $(this).attr('src',$(this).attr('data')); - else $(this).attr('src',''); - }), - Shorty.WUI.Dialog.sharpen(dialog,false) - ).done(dfd.resolve) - } - else - dfd.resolve(); - return dfd.promise(); - }, // Shorty.WUI.Dialog.reset - // ===== Shorty.WUI.Dialog.sharpen ===== - sharpen: function(dialog,sharpness){ - if (Shorty.Debug) Shorty.Debug.log("toggle sharpness of dialog '"+dialog.attr('id')+"' to "+sharpness); - var confirm=dialog.find('#confirm'); - if (sharpness){ - $('#dialog-add #busy').fadeOut('slow'); - confirm.unbind('click'); - confirm.bind('click',{dialog: dialog}, function(event){event.preventDefault();Shorty.WUI.Dialog.execute(event.data.dialog);}); - confirm.addClass('sharp'); - }else{ - confirm.unbind('click'); - confirm.bind('click',function(event){event.preventDefault();dialog.find('#target').effect('highlight',{'color':'#CCCCCC'},500);}); - confirm.removeClass('sharp'); - } - }, // Shorty.WUI.Dialog.sharpen - // ===== Shorty.WUI.Dialog.show ===== - show: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("show dialog "+dialog.attr('id')); - var duration = 'slow'; - var dfd = new $.Deferred(); - if (dialog.is(':visible')) - // dialog already open, nothing to do... - dfd.resolve(); - else{ - $('#content form.shorty-dialog').each(function(){ - Shorty.WUI.Dialog.hide($(this)); - }); - // hide 'old' notifications - Shorty.WUI.Notification.hide(), - // some preparations - $.when( - function(){ - var dfd = new $.Deferred(); - if (dialog.hasClass('shorty-standalone')) - $.when(Shorty.WUI.Desktop.hide()).done(dfd.resolve) - else dfd.resolve(); - return dfd.promise(); - }() - ).pipe(function(){ - // prevent submission before entering anything - Shorty.WUI.Dialog.sharpen(dialog,false); - // show dialog - dialog.slideDown(duration); - }).pipe(function(){ - // initialize dialog actions - switch(dialog.attr('id')){ - case 'dialog-add': - dialog.find('#target').focus(); - dialog.find('#target').bind('focusout', {dialog: dialog}, function(event){Shorty.WUI.Meta.collect(event.data.dialog);}); - break; - case 'dialog-edit': - dialog.find('#title').focus(); - Shorty.WUI.Dialog.sharpen(dialog,true); - break; - } // switch - }).done(dfd.resolve) - } - return dfd.promise(); - }, // Shorty.WUI.Dialog.show - // ===== Shorty.WUI.Dialog.toggle ===== - toggle: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("toggle dialog "+dialog.attr('id')); - var dfd = new $.Deferred(); - Shorty.WUI.Notification.hide(); - // show or hide dialog - if ( ! dialog.is(':visible')) - $.when(Shorty.WUI.Dialog.show(dialog)).done(dfd.resolve) - else - $.when(Shorty.WUI.Dialog.hide(dialog)).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Dialog.toggle - // ===== Shorty.WUI.Dialog.wipe ===== - wipe: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("wipe dialog "+dialog.attr('id')); - var dfd = new $.Deferred(); - if (dialog){ - // wipe dialog fields - $.when( - $.each(dialog.find('#status'), function(){$(this).attr('data','blocked');$(this).val('blocked');}), - $.each(dialog.find('input'), function(){$(this).attr('data','');$(this).val('');}), - $.each(dialog.find('textarea'), function(){$(this).attr('data','');$(this).val('');}), - $.each(dialog.find('.shorty-value'),function(){$(this).attr('data','');$(this).text('');}), - $.each(dialog.find('.shorty-icon'), function(){$(this).attr('data','');$(this).attr('src','');}), - Shorty.WUI.Dialog.sharpen(dialog,false) - ).done(dfd.resolve) - } - else - dfd.resolve(); - return dfd.promise(); - }, // Shorty.WUI.Dialog.wipe - }, // Shorty.WUI.Dialog - // ===== Shorty.WUI.Entry ===== - Entry: - { - // ===== Shorty.WUI.Entry.click ===== - click: function(event,element){ - var dfd = new $.Deferred(); - var entry=element.parents('tr').eq(0); - if (Shorty.Debug) Shorty.Debug.log(event.type+" on action "+element.attr('id')+" for entry "+entry.attr('id')); - // - if ($('.shorty-dialog').is(':visible')) - $('.shorty-dialog').each(function(){Shorty.WUI.Dialog.hide($(this));}); - else{ - // highlight clicked row as active entry - $.when( - Shorty.WUI.List.highlight(entry) - ).pipe(function(){ - if ('click'==event.type){ - switch(element.attr('id')){ - case 'del': Shorty.WUI.Entry.del(entry); break; - case 'edit': Shorty.WUI.Entry.edit(entry); break; - case 'open': Shorty.Action.Url.forward(entry); break; - case 'share': Shorty.WUI.Entry.share(entry); break; - case 'show': Shorty.WUI.Entry.show(entry); break; - } // switch - } // if click - }).done(dfd.resolve) - } // else - return dfd.promise(); - }, // Shorty.WUI.Entry.click - // ===== Shorty.WUI.Entry.del ===== - del: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("delete entry "+entry.attr('id')); - if (entry.hasClass('deleted')){ - // change status to deleted - Shorty.Action.Url.status(entry.attr('data-id'),'blocked'); - // mark row as undeleted - entry.removeClass('deleted'); - }else{ - // change status to deleted - Shorty.Action.Url.status(entry.attr('data-id'),'deleted'); - // mark row as deleted - entry.addClass('deleted'); - } - }, // Shorty.WUI.Entry.del - // ===== Shorty.WUI.Entry.edit ===== - edit: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("modify entry "+entry.attr('id')); - var dfd = new $.Deferred(); - // use the existing edit dialog for this - var dialog=$('#controls #dialog-edit'); - // load entry into dialog - dialog.find('#id').val(entry.attr('data-id')); - dialog.find('#status').val(entry.attr('data-status')||''); - dialog.find('#source').val(entry.attr('data-source'||'')); - dialog.find('#target').val(entry.attr('data-target'||'')); - dialog.find('#title').val(entry.attr('data-title')||''); - dialog.find('#clicks').val(entry.attr('data-clicks')||''); - dialog.find('#created').val(entry.attr('data-created')||''); - dialog.find('#accessed').val(entry.attr('data-accessed')||''); - dialog.find('#notes').val(entry.attr('data-notes')||''); -// dialog.find('#until').datepicker('setDate',new Date(entry.attr('data-until'))||''); - dialog.find('#until').datepicker('setDate',new Date(entry.attr('data-until'))||'') - .datepicker('refresh'); - // open edit dialog - Shorty.WUI.Dialog.show(dialog) - $.when( - Shorty.WUI.Meta.get(entry.attr('data-target')) - ).pipe(function(response){ - var meta=response.data; - if (meta.final) - dialog.find('#target').val(meta.final); - dialog.find('#title').attr('placeholder',meta.title); - dialog.find('#meta').fadeTo('fast',0,function(){ - Shorty.WUI.Meta.reset(dialog); - // specify the icons and information to be shown as meta data - dialog.find('#staticon').attr('src',meta.staticon); - dialog.find('#schemicon').attr('src',meta.schemicon); - dialog.find('#favicon').attr('src',meta.favicon); - dialog.find('#mimicon').attr('src',meta.mimicon); - dialog.find('#explanation').html(meta.title?meta.title:'[ '+meta.explanation+' ]'); - dialog.find('#meta').fadeTo('fast',1); - }) - }).done(function(){ - Shorty.WUI.Dialog.sharpen(dialog,true); - dfd.resolve(); - }).fail(function(){ - Shorty.WUI.Dialog.sharpen(dialog,false); - dfd.reject(); - }) - return dfd.promise(); - }, // Shorty.WUI.Entry.edit - // ===== Shorty.WUI.Entry.send ===== - send: function(event,element){ - var dfd = new $.Deferred(); - var action=element.attr('id'); - var entry=element.parents('tr'); - if (Shorty.Debug) Shorty.Debug.log("send action "+action+" on entry "+entry.attr('data-id')); - // take action - $.when( - Shorty.Action.Url.send(action,entry) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Entry.send - // ===== Shorty.WUI.Entry.share ===== - share: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("share entry "+entry.attr('id')); - var dfd = new $.Deferred(); - // use the existing 'share' dialog for this - var dialog=$('#dialog-share'); - // fill and show dialog - dialog.find('#id').val(entry.attr('data-id')) - .attr('data',entry.attr('data-id')); - dialog.find('#source').attr('href',entry.attr('data-source')) - .text(entry.attr('data-source')); - dialog.find('#relay').attr('href',entry.attr('data-relay')) - .text(entry.attr('data-relay')); - dialog.find('#target').attr('href',entry.attr('data-target')) - .text(entry.attr('data-target')); - dialog.find('#status').attr('value',entry.attr('data-status')) - .attr('data',entry.attr('data-status')); - // move 'share' dialog towards entry - dialog.appendTo(entry.find('td#actions')), - // open dialog - $.when( - Shorty.WUI.Dialog.show(dialog) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Entry.share - // ===== Shorty.WUI.Entry.show ===== - show: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("show entry "+entry.attr('id')); - var dfd = new $.Deferred(); - // use the existing edit dialog for this - var dialog=$('#controls #dialog-show'); - // load entry into dialog - dialog.find('#id').attr('data-id',entry.attr('data-id')).val(entry.attr('data-id')); - dialog.find('#status').attr('data-status',entry.attr('data-status')||'').val(t('shorty',entry.attr('data-status'))||''); - dialog.find('#source').attr('data-source',entry.attr('data-source')).val(entry.attr('data-source')); - dialog.find('#target').attr('data-target',entry.attr('data-target')).val(entry.attr('data-target')); - dialog.find('#title').attr('data-title',entry.attr('data-title')).val(entry.attr('data-title')); - dialog.find('#until').attr('data-until',entry.attr('data-until')||'').val(entry.attr('data-until')||''); - dialog.find('#clicks').attr('data-clicks',entry.attr('data-clicks')||'').val(entry.attr('data-clicks')||''); - dialog.find('#created').attr('data-created',entry.attr('data-created')||'').val(entry.attr('data-created')||''); - dialog.find('#accessed').attr('data-accessed',entry.attr('data-accessed')||'').val(entry.attr('data-accessed')||''); - dialog.find('#notes').attr('data-notes',entry.attr('data-notes')).val(entry.attr('data-notes')); - // open edit dialog - Shorty.WUI.Dialog.show(dialog) - $.when( - Shorty.WUI.Meta.get(entry.attr('data-target')) - ).pipe(function(response){ - var meta=response.data; - if (meta.final) - dialog.find('#target').val(meta.final); - dialog.find('#title').attr('placeholder',meta.title); - dialog.find('#meta').fadeTo('fast',0,function(){ - Shorty.WUI.Meta.reset(dialog); - // specify the icons and information to be shown as meta data - dialog.find('#staticon').attr('src',meta.staticon); - dialog.find('#schemicon').attr('src',meta.schemicon); - dialog.find('#favicon').attr('src',meta.favicon); - dialog.find('#mimicon').attr('src',meta.mimicon); - dialog.find('#explanation').html(meta.title?meta.title:'[ '+meta.explanation+' ]'); - dialog.find('#meta').fadeTo('fast',1); - }) - }).done(function(){ - dfd.resolve(); - }).fail(function(){ - dfd.reject(); - }) - return dfd.promise(); - } // Shorty.WUI.Entry.show - }, // Shorty.WUI.Entry - // ===== Shorty.WUI.Hourglass ===== - // Shorty.WUI.Hourglass - Hourglass: - { - // ===== Shorty.WUI.Hourglass.toggle ===== - toggle: function(show){ - if (Shorty.Debug) Shorty.Debug.log("toggle hourglass to "+show?"true":"false"); - var dfd = new $.Deferred(); - var hourglass = $('#desktop .shorty-hourglass'); - if (show){ - if (hourglass.is(':visible')) - dfd.resolve(); - else - $.when( - hourglass.fadeIn('fast') - ).done(dfd.resolve) - }else{ - if (!hourglass.is(':visible')) - dfd.resolve(); - else - $.when( - hourglass.fadeOut('slow') - ).done(dfd.resolve) - } - return dfd.promise(); - }, // Shorty.WUI.Hourglass.toggle - }, // Shorty.WUI.Hourglass - // ===== Shorty.WUI.List ===== - List: - { - // ===== Shorty.WUI.List.add ===== - add: function(list,hidden){ - if (Shorty.Debug) Shorty.Debug.log("add entry to list holding "+list.length+" entries"); - var dfd = new $.Deferred(); - // insert list elements (sets) one by one - var row,set; - $.each(list,function(i,set){ - // clone dummy row from list header: dummy is the last row - row = $('#desktop #list thead tr:last-child').eq(0).clone(); - // set row id to entry id - row.attr('id',set.id); - // add attributes to row, as data and value - $.each(['id','status','title','source','relay','target','clicks','created','accessed','until','notes','favicon'], - function(j,aspect){ - if (hidden) - row.addClass('shorty-fresh'); // might lead to a pulsate effect later - // we wrap the cells content into a span tag - var span=$(''); - // enhance row with real set values - if ('undefined'==set[aspect]) - row.attr('data-'+this,''); - else row.attr('data-'+this,set[aspect]); - // fill data into corresponsing column - var title, content, classes=[]; - switch(aspect) - { - case 'favicon': - span.html(''); - break; - case 'until': - if (null==set[aspect]) - span.text('-never-'); - else{ - span.text(set[aspect]); - if (Shorty.Date.expired(set[aspect])) - row.addClass('shorty-expired'); - } - break; - case 'title': - span.text(set[aspect]); - span.addClass('ellipsis'); - break; - case 'target': - span.text(set[aspect]); - span.attr('title',set[aspect]); - span.addClass('ellipsis'); - break; - case 'status': - if ('deleted'==set[aspect]) - row.addClass('deleted'); -// span.text(set[aspect]); - span.text(t('shorty',set[aspect])); - break; - default: - span.text(set[aspect]); - } // switch - row.find('td#'+aspect).empty().append(span); - }) // each aspect - // insert new row in table - $('#desktop #list tbody').prepend(row); - }) // each - return dfd.promise(); - }, // Shorty.WUI.List.add - // ===== Shorty.WUI.List.build ===== - build: function() - { - if (Shorty.Debug) Shorty.Debug.log("build list"); - var dfd = new $.Deferred(); - // prepare loading - $.when( - Shorty.WUI.Hourglass.toggle(true), - Shorty.WUI.List.dim(false) - ).done(function(){ - // retrieve new entries - $.when( - Shorty.WUI.List.get() - ).pipe(function(response){ - Shorty.WUI.List.fill(response.data); - }).done(function(){ - $.when( - Shorty.WUI.List.show(), - Shorty.WUI.List.dim(true) - ).always(function(){ - Shorty.WUI.Hourglass.toggle(false) - dfd.resolve(); - }) - }).fail(function(){ - dfd.reject(); - }) - }) - return dfd.promise(); - }, // Shorty.WUI.List.build - // ===== Shorty.WUI.List.dim ===== - dim: function(show){ - if (Shorty.Debug) Shorty.Debug.log("dim list to "+(show?"true":"false")); - var duration='slow'; - var dfd =new $.Deferred(); - var list=$('#desktop #list'); - var body=list.find('tbody'); - if (show) - { - var rows=body.find('tr.shorty-fresh'); - Shorty.WUI.List.highlight(rows.eq(0)); - rows.each(function(){ - $(this).removeClass('shorty-fresh'); - $(this).find('td').effect('pulsate'); - }); - $.when( - Shorty.WUI.List.vacuum(), - body.fadeIn(duration) - ).done(dfd.resolve) - }else{ - if (!body.is(':visible')) - dfd.resolve(); - else - { - $.when( - body.fadeOut(duration) - ).done(dfd.resolve) - } - } - return dfd.promise(); - }, // Shorty.WUI.List.dim - // ===== Shorty.WUI.List.empty ===== - empty: function(){ - if (Shorty.Debug) Shorty.Debug.log("empty list"); - var dfd = new $.Deferred(); - // move embedded dialogs back to their safe place in the controls - $('.shorty-embedded').appendTo($('#controls #dialog-show')); - // remove all rows, one by one - $.when( - $('#desktop').find('#list tbody tr').each(function(){ - if(''!=$(this).attr('id')) - $(this).remove(); - }) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.List.empty - // ===== Shorty.WUI.List.fill ===== - fill: function(list){ - if (Shorty.Debug) Shorty.Debug.log("fill list"); - var dfd = new $.Deferred(); - $.when( - Shorty.WUI.Sums.fill(), - Shorty.WUI.List.empty(), - Shorty.WUI.List.add(list,false) - ).pipe( - // filter list - Shorty.WUI.List.filter('target',$('#list thead tr#toolbar th#target #filter').val()), - Shorty.WUI.List.filter('title', $('#list thead tr#toolbar th#title #filter').val()), - Shorty.WUI.List.filter('status',$('#list thead tr#toolbar th#status select :selected').val()) - ).pipe( - // sort list - $.when( - Shorty.Action.Preference.get('list-sort-code') - ).done(function(pref){ - Shorty.WUI.List.sort(pref['list-sort-code']); - }) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.List.fill - // ===== Shorty.WUI.List.filter ===== - filter: function(column,pattern){ - if (Shorty.Debug) Shorty.Debug.log("filter list by column "+column); - var dfd = new $.Deferred(); - $.when( - $('#list tbody tr').filter(function(){ - return (-1==$(this).find('td#'+column+' span').text().toLowerCase().indexOf(pattern.toLowerCase())); - }).addClass('shorty-filtered'), - $('#list tbody tr').not(function(){ - return (-1==$(this).find('td#'+column+' span').text().toLowerCase().indexOf(pattern.toLowerCase())); - }).removeClass('shorty-filtered') - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.List.filter - // ===== Shorty.WUI.List.get ===== - get: function(){ - if (Shorty.Debug) Shorty.Debug.log("get list"); - var dfd = new $.Deferred(); - $.when( - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','list.php'), - cache: false - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ) - ).done(function(response){ - dfd.resolve(response); - }).fail(function(response){ - dfd.reject(response); - }) - return dfd.promise(); - }, // Shorty.WUI.List.get - // ===== Shorty.WUI.List.hide ===== - hide: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("hide list"); - duration = 'slow'; - var dfd = new $.Deferred(); - var list = $('#desktop #list'); - if ( ! list.is(':visible')) - dfd.resolve(); - else - { - $.when( - list.fadeOut(duration) - ).done(dfd.resolve) - } - return dfd.promise(); - }, // Shorty.WUI.List.hide - // ===== Shorty.WUI.List.highlight ===== - highlight: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("highlighting list entry "+entry.attr('id')); - var dfd = new $.Deferred(); - // close any open embedded dialog - $.when( - Shorty.WUI.Dialog.hide($('.shorty-dialog')) - ).pipe(function(){ - // neutralize all rows that might have been highlighted - $('#desktop #list tr').removeClass('clicked'); - entry.addClass('clicked'); - }).always(dfd.resolve); - return dfd.promise(); - }, // Shorty.WUI.List.highlight - // ===== Shorty.WUI.List.modify ===== - modify: function(list,hidden){ - if (Shorty.Debug) Shorty.Debug.log("modify entry in list holding "+list.length+" entries"); - var dfd = new $.Deferred(); - // modify list elements (sets) one by one - var row,set; - $.each(list,function(i,set){ - // select row from list by id - row=$('#desktop #list tbody tr#'+set.id); - // modify attributes in row, as data and value - $.each(['status','title','until','notes'], - function(j,aspect){ - if (set[aspect]){ - // enhance row with actual set values - row.attr('data-'+this,set[aspect]); - if (hidden) row.addClass('shorty-fresh'); - // fill data into corresponsing column - var content, classes=[]; - switch(aspect) - { - case 'until': - if (null==set[aspect]) - content='-never-'; - else{ - content=set[aspect]; - if (Shorty.Date.expired(set[aspect])) - row.addClass('shorty-expired'); - } - break; - case 'title': - classes.push('ellipsis'); - content=set[aspect]; - break; - case 'status': - if ('deleted'==set[aspect]) - row.addClass('deleted'); - content=set[aspect]; - break; - default: - content=set[aspect]; - } // switch - // show modified column immediately or keep it for a later pulsation effect ? - row.find('td').filter('#'+aspect).html(''+content+''); - } // if aspect - }) // each aspect - }) // each entry - return dfd.resolve().promise(); - }, // Shorty.WUI.List.modify - // ===== Shorty.WUI.List.show ===== - show: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("show list"); - duration = 'slow'; - var dfd = new $.Deferred(); - var list = $('#desktop #list'); - if (list.is(':visible')) - dfd.resolve(); - else - { - // list currently not visible, show it - $.when( - list.find('tbody').show(), - list.fadeIn(duration) - ).done(function(){ - dfd.resolve(); - Shorty.WUI.List.vacuum(); - }) - } - return dfd.promise(); - }, // Shorty.WUI.List.show - // ===== Shorty.WUI.List.sort ===== - sort: function(sortCode){ - sortCore = sortCode || 'cd'; - var icon=$('#list thead tr#toolbar th div img[data-sort-code="'+sortCode+'"]'); - var sortCol=icon.parents('th').attr('id'); - var sortDir=icon.attr('data-sort-direction'); - if (Shorty.Debug) Shorty.Debug.log("sorting list column "+sortCol+" "+(sortDir=='asc'?'ascending':'descending')); - // use the 'tinysort' jquery plugin for sorting - switch (sortCol){ - case 'until': - $('#list tbody>tr').tsort('td#until',{order:sortDir}); - break; - default: - $('#list tbody>tr').tsort({attr:'data-'+sortCol,order:sortDir}); - } // switch - // mark currently active sort icon - var icons=$('#list thead tr#toolbar img.shorty-sorter'); - icons.removeClass('shorty-active'); - icons.filter('[data-sort-code="'+sortCode+'"]').addClass('shorty-active'); - // store the sorting code as preference, for returning list retrievals - Shorty.Action.Preference.set({'list-sort-code':sortCode}); - }, // Shorty.WUI.List.sort - // ===== Shorty.WUI.List.toggle ===== - toggle: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("toggle list"); - duration = 'slow'; - var dfd = new $.Deferred(); - if (list.is(':visible')) - return Shorty.WUI.List.hide(); - else - return Shorty.WUI.List.show(); - }, // Shorty.WUI.List.toggle - // ===== Shorty.WUI.List.vacuum ===== - vacuum: function(){ - if (Shorty.Debug) Shorty.Debug.log("vacuum list"); - // list is empty if no row exists - if (0!=$('#list tbody').find('tr').length) - $('#vacuum').fadeOut('fast'); - else - $('#vacuum').fadeIn('slow'); - }, // Shorty.WUI.List.vacuum - // ===== Shorty.WUI.List.Toolbar ===== - Toolbar: - { - // ===== Shorty.WUI.List.Toolbar.toggle ===== - toggle: function(duration){ - if (Shorty.Debug) Shorty.Debug.log("toggle list toolbar"); - duration = duration || 'slow'; - var button=$('#list #tools'); - var toolbar=$('#list #toolbar'); - var dfd = new $.Deferred(); - if (!toolbar.find('div').is(':visible')){ - // tool NOT visible: open toolbar - $.when( - toolbar.find('div').slideDown(duration) - ).pipe( - button.attr('src',button.attr('data-minus')) - ).done(dfd.resolve) - }else{ // toolbar IS visible - // any filters active? prevent closing of toolbar ! - if ( ( (toolbar.find('th#title,#target').find('div input#filter:[value!=""]').length) - &&(toolbar.find('th#title,#target').find('div input#filter:[value!=""]').effect('pulsate')) ) - ||( (toolbar.find('th#status select :selected').val()) -// &&(toolbar.find('#status div.chzn-container').effect('pulsate')) ) - &&(toolbar.find('#status').effect('pulsate')) ) - ) { - if (Shorty.Debug) Shorty.Debug.log('active filter prevents closing of toolbar'); - }else{ - // close toolbar - $.when( - toolbar.find('div').slideUp(duration) - ).pipe( - button.attr('src',button.attr('data-plus')) - ).done(dfd.resolve) - } - } - return dfd.promise(); - }, // Shorty.WUI.List.Toolbar.toggle - }, // Shorty.WUI.List.Toolbar - }, // Shorty.WUI.List - // ===== Shorty.WUI.Notification ===== - Notification: - { - // ===== Shorty.WUI.Notification.hide ===== - hide: function(){ - if (Shorty.Debug) Shorty.Debug.log("hide notification"); - var dfd = new $.Deferred(); - $.when( - $('#notification').slideUp('fast') - ).pipe(function(){ - $('#notification').text(''); - }).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Notification.hide - // ===== Shorty.WUI.Notification.show ===== - show: function(message,level){ - if (Shorty.Debug) Shorty.Debug.log("show notification with level "+level); - level = level || 'info'; - var dfd = new $.Deferred(); - var duration = 'slow'; - var notification = $('#notification'); - if (message && message.length){ - $.when( - notification.slideUp('fast') - ).done(function(){ - switch(level){ - case 'debug': - // detect debug mode by checking, of function 'debug()' exists - if ( Shorty.Debug ){ - Shorty.Debug.log('Debug: '+message); - $.when( - notification.attr('title', 'debug message'), - notification.text('Debug: '+message), - notification.slideDown(duration) - ).done(dfd.resolve) - } - else - dfd.resolve(); - break; - case 'error': - if (Shorty.Debug) - Shorty.Debug.log('Error: '+message); - $.when( - notification.attr('title', 'error message'), - notification.text('Error: ' + message), - notification.slideDown(duration) - ).done(dfd.resolve) - break; - default: // 'info' - if ( message.length ){ - if (Shorty.Debug) - Shorty.Debug.log('Info: '+message); - $.when( - notification.text(message), - notification.slideDown(duration) - ).done(dfd.resolve) - }else{ - $.when( - notification.text('') - ).done(dfd.resolve) - } - } // switch - }) - } // if message - return dfd.promise(); - }, // Shorty.WUI.Notification.show - }, // Shorty.WUI.Notification - // ===== Shorty.WUI.Meta: ===== - Meta: - { - // ===== Shorty.WUI.Meta.collect ===== - collect: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("collect meta data"); - var dfd = new $.Deferred(); - var target = $('#dialog-add #target').val().trim(); - // don't bother getting active on empty input - if ( ! target.length ){ - dialog.find('#target').focus(); - dfd.resolve(); - return dfd.promise(); - } - // start expressing activity - $('#dialog-add #busy').fadeIn('fast'); - // fill in fallback protocol scheme 'http' if none is specified - var regexp = /^[a-zA-Z0-9]+\:\//; - if ( ! regexp.test(target) ){ - target = 'http://' + target; - dialog.find('#target').val(target); - } - // query meta data from target - $.when( - Shorty.WUI.Meta.get(target) - ).done(function(response){ - var meta=response.data; - if (meta.final) - dialog.find('#target').val(meta.final); - dialog.find('#title').attr('placeholder',meta.title); - dialog.find('#meta').fadeTo('fast',0,function(){ - Shorty.WUI.Meta.reset(dialog); - // specify the icons and information to be shown as meta data - dialog.find('#staticon').attr('src',meta.staticon); - dialog.find('#schemicon').attr('src',meta.schemicon); - dialog.find('#favicon').attr('src',meta.favicon); - dialog.find('#mimicon').attr('src',meta.mimicon); - dialog.find('#explanation').html(meta.title?meta.title:'[ '+meta.explanation+' ]'); - dialog.find('#meta').fadeTo('fast',1); - Shorty.WUI.Dialog.sharpen(dialog,true); - // stop expressing activity - $('#dialog-add #busy').fadeOut('slow'); - }); - dfd.resolve(response); - }).fail(function(reponse){ - Shorty.WUI.Dialog.sharpen(dialog,false); - dfd.reject(response); - }) - return dfd.promise(); - }, // Shorty.WUI.Meta.collect - // ===== Shorty.WUI.Meta.get ===== - get: function(target){ - if (Shorty.Debug) Shorty.Debug.log("get meta data for target "+target); - var dfd = new $.Deferred(); - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','meta.php'), - cache: false, - data: { target: encodeURIComponent(target) } - }).pipe( - function(response){return Shorty.Ajax.eval(response);}, - function(response){return Shorty.Ajax.fail(response);} - ).done(function(response){ - dfd.resolve(response); - }).fail(function(response){ - dfd.reject(response); - }) - return dfd.promise(); - }, // Shorty.WUI.Meta.get - // ===== Shorty.WUI.Meta.reset ===== - reset: function(dialog){ - if (Shorty.Debug) Shorty.Debug.log("reset meta data"); - dialog.find('#staticon').attr('src',dialog.find('#staticon').attr('data')); - dialog.find('#schemicon').attr('src',dialog.find('#schemicon').attr('data')); - dialog.find('#favicon').attr('src',dialog.find('#favicon').attr('data')); - dialog.find('#mimicon').attr('src',dialog.find('#mimicon').attr('data')); - dialog.find('#explanation').html(dialog.find('#explanation').attr('data')); - dialog.find('#meta').fadeTo('fast',1); - }, // Shorty.WUI.Meta.reset - }, // Shorty.WUI.Meta - // ===== Shorty.WUI.Sums ===== - Sums: - { - // ===== Shorty.WUI.Sums.fill ===== - fill: function(){ - if (Shorty.Debug) Shorty.Debug.log("fill sums"); - var dfd = new $.Deferred(); - $.when( - // update (set) sum values in the control bar - Shorty.WUI.Sums.get(function(data){ - $('#controls #sum_shortys').text(data.sum_shortys); - $('#controls #sum_clicks').text(data.sum_clicks); - }) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.WUI.Sums.fill - // ===== Shorty.WUI.Sums.get ===== - get: function(callback){ - if (Shorty.Debug) Shorty.Debug.log("get sums"); - var dfd = new $.Deferred(); - $.when( - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','count.php'), - cache: false, - data: { } - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ) - ).done(function(response){ - if (callback) callback(response.data); - dfd.resolve(response); - }).fail(function(response){ - dfd.reject(response); - }) - return dfd.promise(); - }, // Shorty.WUI.Sums.get - }, // Shorty.WUI.Sums - }, // Shorty.WUI - - //========== - - Action: - { - // ===== Shorty.Action.Preference ===== - Preference: - { - // ===== Shorty.Action.Preference.get ===== - get:function(data){ - if (Shorty.Debug){Shorty.Debug.log("get preference(s):");Shorty.Debug.log(data);} - var dfd = new $.Deferred(); - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','preferences.php'), - cache: false, - data: data - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).always(function(response){ - if (Shorty.Debug){Shorty.Debug.log("got preference(s):");Shorty.Debug.log(response.data);} - }).done(function(response){ - dfd.resolve(response.data); - }).fail(function(response){ - dfd.reject({}); - }) - return dfd.promise(); - }, // Shorty.Action.Preference.get - // ===== Shorty.Action.Preference.set ===== - set:function(data){ - if (Shorty.Debug){Shorty.Debug.log("set preference(s):");Shorty.Debug.log(data);} - var dfd = new $.Deferred(); - $.ajax({ - type: 'POST', - url: OC.filePath('shorty','ajax','preferences.php'), - cache: false, - data: data - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).always(function(response){ - if (Shorty.Debug){Shorty.Debug.log("got preference(s):");Shorty.Debug.log(response.data);} - }).done(function(response){ - dfd.resolve(response.data); - }).fail(function(response){ - dfd.reject({}); - }) - return dfd.promise(); - }, // Shorty.Action.Preference.set - }, // Shorty.Action.Preference - // ===== Shorty.Action.Setting ===== - Setting: - { - // ===== Shorty.Action.Setting.get ===== - get:function(data){ - if (Shorty.Debug){Shorty.Debug.log("get setting(s):");Shorty.Debug.log(data);} - var dfd = new $.Deferred(); - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','settings.php'), - cache: false, - data: data - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).always(function(response){ - if (Shorty.Debug){Shorty.Debug.log("got preference(s):");Shorty.Debug.log(response.data);} - }).done(function(response){ - dfd.resolve(response.data); - }).fail(function(response){ - dfd.reject({}); - }) - return dfd.promise(); - }, // Shorty.Action.Setting.get - // ===== Shorty.Action.Setting.set ===== - set:function(data){ - if (Shorty.Debug){Shorty.Debug.log("set setting(s):");Shorty.Debug.log(data);} - var dfd = new $.Deferred(); - $.ajax({ - type: 'POST', - url: OC.filePath('shorty','ajax','settings.php'), - cache: false, - data: data - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).always(function(response){ - if (Shorty.Debug){Shorty.Debug.log("got preference(s):");Shorty.Debug.log(response.data);} - }).done(function(response){ - dfd.resolve(response.data); - }).fail(function(response){ - dfd.reject({}); - }) - return dfd.promise(); - }, // Shorty.Action.Setting.set - // ===== Shorty.Action.Setting.popup ===== - popup:{}, - // ===== Shorty.Action.Setting.verify ===== - verify:function(){ - if (!Shorty.Action.Setting.popup.dialog){ - Shorty.Action.Setting.popup=$('#shorty #dialog-verification'); - Shorty.Action.Setting.popup.dialog({show:'fade',autoOpen:false,modal:true}); - Shorty.Action.Setting.popup.dialog('option','minHeight',240 ); - } - var dfd = new $.Deferred(); - $.when( - this.check(Shorty.Action.Setting.popup, - $('#shorty #backend-static #backend-static-base').val()) - ).done(dfd.resolve) - return dfd.promise(); - }, // Shorty.Action.Setting.verify - // ===== Shorty.Action.Setting.check ===== - check:function(popup,target){ - popup.find('#verification-target').text(target); - popup.dialog('open'); - popup.find('#success').hide(); - popup.find('#failure').hide(); - popup.find('#hourglass').fadeIn('fast'); - var dfd = new $.Deferred(); - $.ajax({ - // the '0000000000' below is a special id recognized for testing purposes - url: target+'0000000000', - cache: false, - data: { }, - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).done(function(response){ - $.when( - popup.find('#hourglass').fadeOut('fast') - ).then(function(){ - popup.find('#success').fadeIn('fast'); - dfd.resolve(response); - }) - }).fail(function(response){ - $.when( - popup.find('#hourglass').fadeOut('fast') - ).then(function(){ - popup.find('#failure').fadeIn('fast'); - dfd.reject(response); - }) - }) - return dfd.promise(); - } // Shorty.Action.Setting.check - }, // Shorty.Action.Setting - // ===== Shorty.Action.Url ===== - Url: - { - // ===== Shorty.Action.Url.add ===== - add:function(){ - if (Shorty.Debug) Shorty.Debug.log("action add url"); - var dfd=new $.Deferred(); - var dialog=$('#dialog-add'); - var status=dialog.find('#status').val()||'public'; - var target=dialog.find('#target').val()||''; - var title =dialog.find('#title').val()||''; - var notes =dialog.find('#notes').val()||''; - var until =dialog.find('#until').val()||''; - // store favicon from meta data, except it is the internal default blank - var favicon = dialog.find('#meta #favicon').attr('src'); - favicon=(favicon==dialog.find('#meta #favicon').attr('data'))?'':favicon; - // perform upload of new shorty - $.when( - Shorty.WUI.Notification.hide(), - // close and neutralize dialog - Shorty.WUI.Dialog.hide(dialog), - Shorty.WUI.List.dim(false), - Shorty.WUI.List.show() - ).done(function(){ - var data={status: status, - target: target, - title: title, - notes: notes, - until: until, - favicon: favicon}; - if (Shorty.Debug) Shorty.Debug.log(data); - $.ajax({ - type: 'POST', - url: OC.filePath('shorty','ajax','add.php'), - cache: false, - data: data - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).done(function(response){ - // wipe entries in dialog - Shorty.WUI.Dialog.reset(dialog) - }).done(function(response){ - // add shorty to existing list - Shorty.WUI.List.add([response.data],true); - Shorty.WUI.List.dim(true) - dfd.resolve(response); - }).fail(function(response){ - Shorty.WUI.List.dim(true) - dfd.reject(response); - }) - }) - return dfd.promise(); - }, // ===== Shorty.Action.Url.add ===== - // ===== Shorty.Action.Url.edit ===== - edit: function(){ - if (Shorty.Debug) Shorty.Debug.log("action modify url"); - var dfd=new $.Deferred(); - var dialog=$('#dialog-edit'); - var id =dialog.find('#id').val(); - var status=dialog.find('#status').val()||'blocked'; - var title =dialog.find('#title').val()||''; - var until =dialog.find('#until').val()||''; - var notes =dialog.find('#notes').val()||''; - // perform modification of existing shorty - $.when( - Shorty.WUI.Notification.hide(), - // close and neutralize dialog - Shorty.WUI.Dialog.hide(dialog), - Shorty.WUI.List.dim(false), - Shorty.WUI.List.show() - ).done(function(){ - var data={id: id, - status: status, - title: title, - notes: notes, - until: until}; - if (Shorty.Debug) Shorty.Debug.log(data); - $.ajax({ - type: 'POST', - url: OC.filePath('shorty','ajax','edit.php'), - cache: false, - data: data, - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).done(function(response){ - // wipe entries in dialog - Shorty.WUI.Dialog.reset(dialog); - // modify existing entry in list - Shorty.WUI.List.modify([response.data],true); - Shorty.WUI.List.dim(true) - dfd.resolve(response); - }).fail(function(response){ - dfd.reject(response); - }) - }) - return dfd.promise(); - }, // ===== Shorty.Action.Url.edit ===== - // ===== Shorty.Action.Url.del ===== - del: function(){ - if (Shorty.Debug) Shorty.Debug.log("action delete url"); - var dfd = new $.Deferred(); - var dialog = $('#dialog-edit'); - var id = dialog.find('#id').val(); - $.when( -// Shorty.WUI.Notification.hide(), - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','del.php'), - cache: false, - data: { id: id } - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ) - ).done(function(response){ - // close and neutralize dialog - Shorty.WUI.Dialog.hide(dialog); - // hide and remove deleted entry - // ... - dfd.resolve(response.data); - }).fail(function(response){ - dfd.reject(response.data); - }) - return dfd.promise(); - }, // ===== Shorty.Action.Url.del ===== - // ===== Shorty.Action.Url.forward ===== - forward: function(entry){ - if (Shorty.Debug) Shorty.Debug.log("action forward to entry "+entry.attr('id')); - var url=entry.attr('data-target'); - if (Shorty.Debug) Shorty.Debug.log("opening target url '"+url+"' in new window"); - window.open(url); - }, // Shorty.Action.Url.forward - // ===== Shorty.Action.Url.send ===== - send: function(action,entry){ - if (Shorty.Debug) Shorty.Debug.log("action send via "+action+" with entry "+entry.attr('id')); - switch (action){ - case 'usage-email': - var mailSubject=entry.attr('data-title')||''; - var mailBody=entry.attr('data-notes')+"\n\n"+entry.attr('data-source'); - window.location='mailto:""?' - +'subject='+encodeURIComponent(mailSubject) - +'&body='+encodeURIComponent(mailBody); - break; - case 'usage-sms': - var smsBody=entry.attr('data-title')+" - "+entry.attr('data-notes')+" - "+entry.attr('data-source'); - // unfortunately there is no way to get the body over into the sms application on "sms urls"... - window.prompt(t('shorty',"Copy to clipboard: Ctrl+C, then paste into SMS: Ctrl-V"), smsBody ); - window.location='sms:'; - break; - case 'usage-qrcode': - var title =entry.attr('data-title'); - var source=entry.attr('data-source'); - var target=entry.attr('data-target'); - Shorty.Action.Usage.Dialog.qrcode(title,source,target); - break; - case 'usage-clipboard': - window.prompt(t('shorty',"Copy to clipboard: Ctrl+C"), entry.attr('data-source')); - break; - default: - if (Shorty.Debug) Shorty.Debug.log("usage action '"+action+"' is disabled, refusing to comply"); - } - }, // Shorty.Action.Url.send - // ===== Shorty.Action.Url.show ===== - show: function(){ - var dfd = new $.Deferred(); - var dialog = $('#dialog-show'); - var id = dialog.find('#id').val(); - var record = $(this).parent().parent(); - $('#shorty-add-id').val(record.attr('data-id')); - $('#shorty-add-id').val(record.attr('data-status')); - $('#shorty-add-source').val(record.children('.shorty-source:first').text()); - $('#shorty-add-target').val(record.children('.shorty-target:first').text()); - $('#shorty-add-notes').val(record.children('.shorty-notes:first').text()); - $('#shorty-add-until').val(record.children('.shorty-until:first').text()); - $.when( - function(){ - if ($('.shorty-add').css('display') == 'none'){ - $('.shorty-add').slideToggle(); - } - }, - $('html, body').animate({ scrollTop: $('.shorty-menu').offset().top }, 500) - ).done(dfd.resolve) - return dfd.promise(); - }, // ===== Shorty.Action.Url.show ===== - // ===== Shorty.Action.Url.status ===== - status: function(id,status){ - if (Shorty.Debug) Shorty.Debug.log("changing status of id "+id+" to "+status); - var dfd = new $.Deferred(); - $.ajax({ - type: 'GET', - url: OC.filePath('shorty','ajax','status.php'), - cache: false, - data: { id : id, - status: status } - }).pipe( - function(response){return Shorty.Ajax.eval(response)}, - function(response){return Shorty.Ajax.fail(response)} - ).done(function(){ - // update the rows content - var row=$('#list tbody tr#'+id); - row.attr('data-status',status); - row.find('td#status span').text(t('shorty',status)); - dfd.resolve(); - }).fail(dfd.reject) - return dfd.promise(); - } // Shorty.Action.Url.status - }, // ===== Shorty.Action.Url ===== - // ===== Shorty.Action.Usage ===== - Usage: - { - // ===== Shorty.Action.Usage.Popup ===== - Popup: - { - // ===== Shorty.Action.Usage.Popup.qrcode ===== - qrcode:{}, - }, // Shorty.Action.Usage.Popup - // ===== Shorty.Action.Usage.Dialog ===== - Dialog: - { - // ===== Shorty.Action.Usage.Dialog.qrcode ===== - qrcode:function(title,source,target){ - var qrcode=Shorty.Action.Usage.Popup.qrcode; - if (!qrcode.dialog){ - qrcode=$('#dialog-qrcode'); - qrcode.dialog({show:'fade',autoOpen:false,modal:true}); - qrcode.dialog('option','width',240 ); - //qrcode.dialog('option','height',80 ); - } - // a hidden input field ('qrcode-url') holds the base url to the qrcode generator - // we just add the url parameter for this specific entrys source url - var url=qrcode.find('#qrcode-url').val()+encodeURIComponent(source); - qrcode.dialog('option','title',title); - qrcode.find('#qrcode-img img').attr('src',url).attr('title',source); - qrcode.find('#qrcode-val a').text(url); - qrcode.bind('click',function(){ - qrcode.find('#qrcode-img').toggle(); - qrcode.find('#qrcode-val').toggle(); - }); - qrcode.dialog('open'); - } // Shorty.Action.Usage.Dialog.qrcode - } // Shorty.Action.Usage.Dialog - } // Shorty.Action.Usage - }, // Shorty.Action - - // =========== - - // ===== Shorty.Ajax ===== - Ajax: - { - // ===== Shorty.Ajax.eval ===== - eval:function(response){ - if (Shorty.Debug) Shorty.Debug.log("eval ajax response of status "+response.status); - // Check to see if the response is truely successful. - if (response.status){ - // this is a valid response - if ('success'==response.status){ - Shorty.WUI.Notification.show(response.message,'debug'); - return new $.Deferred().resolve(response); - } else { - Shorty.WUI.Notification.show(response.message,'error'); - return new $.Deferred().reject(response); - } -// }else{ - // TEST (regex) if this is a DB error: - // DB Error: "SQLSTATE[HY000]: General error: 1 near "WHERE": syntax error"..... -// // not a valid response, maybe a DB error ? -// if ('DB error'==response) - } - }, // Shorty.Ajax.eval - - // ===== Shorty.Ajax.fail ===== - fail:function(response){ - if (Shorty.Debug) Shorty.Debug.log("handle ajax failure"); - return new $.Deferred().reject({ - status: 'error', - data: null, - message: [ "Unexpected error: " + response.status + " " + response.statusText ] - }); - } // Shorty.Ajax.fail - }, // Shorty.Ajax - - // ==== Shorty.Date ===== - Date: - { - // ===== Shorty.Date.expired ===== - expired:function(date){ - return (Date.parse(date)<=Date.parse(Date())); - } // Shorty.Date.expired - } // Shorty.Date - -} // Shorty diff --git a/apps/shorty/l10n/de.php b/apps/shorty/l10n/de.php deleted file mode 100644 index cc4eb624a0..0000000000 --- a/apps/shorty/l10n/de.php +++ /dev/null @@ -1,157 +0,0 @@ - "alle", -"blocked" => "geblockt", -"deleted" => "gelöscht", -"disabled" => "deaktiviert", -"enabled" => "aktiviert", -"never" => "niemals", -"private" => "privat", -"public" => "öffentlich", -"shared" => "geteilt", - -"bitly.com service" => "bitly.com-Service", -"cli.gs service" => "cli.gs-Service", -"goo.gl service" => "goo.gl-Service", -"is.gd service" => "is.gd-Service", -"ti.ny service" => "ti.ny-Service", -"tiny.cc service" => "tiny.cc-Service", -"static backend" => "statisches Backend", - -"Access" => "Zugriff", -"Add a new shorty" => "Neuen Shorty hinzufügen", -"Add as new" => "Neu hinzufügen", -"Add page as 'Shorty' to ownCloud" => "Seite als 'Shorty' zu ownCloud hinzufügen", -"Anything that appears helpful …" => "Alles, was hilfreich erscheint …", -"Backend" => "Backend", -"Base url" => "Basis-Url", -"Choose a service…" => "Wähle einen Dienst…", -"Click for qrcode image" => "Klicken für QRCode-Bild", -"Click for qrcode url" => "Klicken für QRCode-Url", -"Click it, for whatever site you want to create a Shorty." => "Klicke es, für welche Seite auch immer Du ein 'Shorty' generieren willst.", -"Click registered" => "Click registriert", -"Clicks" => "Klicks", -"Close" => "Schließen", -"Copy to clipboard" => "In die Zwischenablage kopieren", -"Copy to clipboard: Ctrl+C" => "In Zwischenablage kopieren: Strg-C", -"Copy to clipboard: Ctrl+C, then paste into SMS: Ctrl-V" => "In Zwischenablage kopieren: Strg-C, dann in SMS einfügen: Strg-V", -"Counted entries and clicks" => "Einträge und Klicks gezählt", -"Creation" => "Generierung", -"Delete shorty" => "Shorty löschen", -"Drag this to your browser bookmarks." => "Zieh' dies in die Lesezeichen Deines Browsers.", -"Example" => "Beispiel", -"Exception" => "Ausnahme", -"Exception (%s)" => "Ausnahme (%s)", -"Expiration" => "Verfall", -"List currently empty." => "Liste derzeit leer.", -"Loading" => "Lade", -"Modifications for shorty with id '%s' saved" => "Änderungen zu Shorty mit Kennung '%s' gespeichert", -"Modify attributes" => "Attribute ändern", -"Modify shorty" => "Shorty ändern", -"New Shorty" => "Neuer Shorty", -"Notes" => "Notizen", -"Number of entries" => "Anzahl der Einträge", -"Number of entries: %s" => "Anzahl der Einträge: %s", -"QRCode" => "QRCode", -"Open source url" => "Quell-Url öffnen", -"Open relay url" => "Relais-Url öffnen", -"Open target" => "Ziel öffnen", -"Open target url" => "Ziel-Url öffnen", -"Preference saved." => "Präferenz gespeichert.", -"Preference(s) retrieved." => "Präferenz(en) abgefragt.", -"Relay url" => "Relais-Url", -"Reload list" => "Liste neu laden", -"Save" => "Speichern", -"Send by email" => "Als E-Mail verschicken", -"Send by SMS" => "Als SMS verschicken", -"Setting saved." => "Einstellung gespeichert.", -"Shortlet" => "Shortlet", -"Shorty with id '%s' deleted" => "Shorty mit Kennung '%s' gelöscht", -"Shorty source url" => "Shorty Quell-Url", -"Shorty title" => "Shorty-Titel", -"Show details" => "Details zeigen", -"Show as QRCode" => "Als QRCode anzeigen", -"Sort ascending" => "aufsteigend sortieren", -"Sort descending" => "absteigend sortieren", -"Source url" => "Quell-Url", -"Specify a backend base url…" => "Lege eine Basis-Url für das Backend fest…", -"Status" => "Status", -"Status change for shorty with id '%s' saved" => "Statusänderung für Shorty mit Kennung '%s' gespeichert", -"Target" => "Ziel", -"Target url" => "Ziel-Url", -"Target url '%s' is valid" => "Ziel-Url '%s' ist valide", -"Test and use" => "Testen und nutzen", -"Title" => "Titel", -"Total of clicks" => "Summe der Klicks", -"Unexpected type of exception caught: %s" => "Unerwarteter Type einer Ausnahme aufgetreten: %s", -"Unknown object of type caught: %s" => "Unbekanntes Objekttyp aufgetreten: %s", -"Url shortened to: %s" => "Url gekürzt zu: %s", -"Verification by click" => "Prüfung durch Klicken", - -"%s\nMessage(code): %s (%s)\nFile(line): %s (%s)\nInfo: %%s" => "%s\Nachricht(Code): %s (%s)\nDatei(Zeile): %s (%s)\nInfo: %%s", - -"API access key" => "API-Zugriffsschlüssel", -"Account" => "Nutzerkonto", -"API key" => "API-Schlüssel", -"bit.ly user" => "bit.ly-Nutzer", -"bit.ly user name" => "bit.ly-Nutzerkennung", -"bit.ly key" => "bit.ly-Schlüssel", -"bit.ly users key" => "bit.ly-Nutzerschlüssel", -"Google API key" => "Google API-Schlüssel", -"Google API account" => "Google API-Nutzerkonto", -"tiny.cc user" => "tiny.cc-Nutzer", -"tiny.cc user name" => "tiny.cc-Nutzerkennung", -"tiny.cc key" => "tiny.cc-Schlüssel", -"tiny.cc user key" => "tiny.cc-Nutzerschlüssel", - -"The external 'bitly.com' service is used to register a short url for each generated shorty." -=> "Der externe 'bitly.com'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"This means you have to register an '%s' at their site first." -=> "Das bedeutet, zunächst muss ein '%s' auf deren Seite registriert werden.", -"The external 'turl' service is used to register a short url for each generated shorty." -=> "Der externe 'turl'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"The external 'ti.ny' service is used to register a short url for each generated shorty." -=> "Der externe 'ti.ny'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"The external 'cli.gs' service is used to register a short url for each generated shorty." -=> "Der externe 'cli.gs'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"The external 'is.gd' service is used to register a short url for each generated shorty." -=> "Der externe 'is.gd'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"The external 'tiny.cc' service is used to register a short url for each generated shorty." -=>"Der externe 'tiny.cc'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"No backend is used, direct links pointing to your ownCloud are generated." -=> "Kein Backend wird verwendet, einfache direkte Links zur ownCloud werden erzeugt.", -"The service requires you to authenticate yourself by providing a valid bit.ly user name and an '%s'." -=> "Dieser Dienst erfordert die Authentifizierung durch eine valide bit.ly-Nutzerkennung und einen '%s'", -"Such links are most likely longer than those generated when using a backend." -=> "Solche Links werden sicherlich länger sein, als wenn ein Backend eingesetzt wird.", -"However this option does not rely on any third party service and keeps your shortys under your control." -=> "Dafür stützt sich diese Option aber nicht auf fremde Angebote und belässt die Shorties unter eigener Kontrolle.", -"A static, rule-based backend is used, shorty links are generated relative to a given base url." -=> "Ein statisches, regelbasiertes Backend wird genutzt, Shorty-Links werden relativ zu einer gegebenen Basis-Url generiert.", -"Since this setup depends on server based configuration rules the base url can only be specified in the 'Admin' section of the configuration." -=> "Da diese Konfiguration von serverseitigen Konfigurationsregeln abhängt, kann die Basis-Url nur unter 'Verwaltung' in der Konfiguration festgelegt werden.", -"You have to take care that any request to the url configured here is internally mapped to the 'shorty' module." -=> "Es muss sicher gestellt werden, dass jede Anfrage an die hier konfigurierte URL intern umgesetzt wird auf das 'Shorty'-Modul", -"Have a try with the example link provided, click it, it should result in a confirmation that your setup is working." -=> "Einfach den verfügbaren Beispiel-Link durch Anklicken testen. Das sollte zu einer Bestätigung führen, dass die Konfiguration funktioniert.", -"Leave empty if you can't provide a short base url that is mapped the described way." -=> "Einfach leer lassen, wenn keine Basis-URL angegeben werden kann, die wir beschrieben umgesetzt wird.", -"Only use this backend, if you can provide a short base url that is mapped the described way. Your shorties won't work otherwise." -=> "Dieses Backend kann nur verwendet werden, wenn die Basis-Url in der beschriebenen Art umgesetzt wird. Die Shorties werden andernfalls nicht nutzbar sein.", -"Googles external 'goo.gl service' is used to register a short url for each generated shorty." -=> "Googles externer 'goo.gl'-Dienst wird genutzt, um eine Kurz-Url für jeden generierten Shorty zu registrieren.", -"You must provide a valid '%s' to use this service." -=> "Es muss eine valide '%s' angegeben werden um diesen Dienst nutzen zu können. ", -"This means you require a 'Google API console account'." -=> "Das bedeutet, dass ein 'Google API console account' benötigt wird", -"Register a new '%s' at their pages." -=> "Einen neuen '%s' auf deren Seite registrieren.", -"Enabling the SMS option will offer sending a Shorty via SMS." -=> "Aktivieren der SMS-Option bietet das Versenden von Shortys via SMS an.", -"Unfortunately support for 'SMS url handling' is usually only found on mobile devices like smart phones." -=> "Unglücklicherweise werden 'SMS-Urls' typischerweise nur auf mobilen Geräten wie etwa Smartphones unterstützt.", -"In addition, the implementations found in Android or iOS are minimalistic, buggy and differ from system to system." -=> "Darüber hinaus sind die Implementierungen, etwa die in Adroid oder auch iOS minimalistisch, fehlerhaft und unterschiedlich von System zu System.", -"In short: this might not work for you, therefore you can disable it…" -=> "Kurz gesagt: die mag nicht funktionieren, daher can die Option deaktiviert werden…", -); \ No newline at end of file diff --git a/apps/shorty/lib/backend.php b/apps/shorty/lib/backend.php deleted file mode 100644 index aa6c58b449..0000000000 --- a/apps/shorty/lib/backend.php +++ /dev/null @@ -1,286 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file lib/backend.php - * Routines to use remote (online) shortening services as backends in a local workflow - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Backend - * @brief Library to register urls using backends, typically remote (online) url shortening services - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Backend -{ - /** - * @method OC_Shorty_Backend::registerUrl - * @brief Wrapper function around the specific backend routines - * @param id (string) Internal shorty id used to reference a shorty upon usage. - * @returns (string) The shortened url as generated by a specific backend. - * @throws OC_Shorty_Exception taking over the explaining of the failure from the specific backend - * @access public - * @author Christian Reiner - */ - static function registerUrl ( $id ) - { - try - { - // construct the $relay, the url to be called to reach THIS service (ownclouds shorty plugin) - $relay = OC_Shorty_Tools::relayUrl ( $id ); - // call backend specific work horse - switch ( $type=OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-type','none') ) - { - default: return OC_Shorty_Backend::registerUrl_default ( $id, $relay ); - case 'static': return OC_Shorty_Backend::registerUrl_static ( $id, $relay ); - case 'bitly': return OC_Shorty_Backend::registerUrl_bitly ( $id, $relay ); - case 'cligs': return OC_Shorty_Backend::registerUrl_cligs ( $id, $relay ); - case 'google': return OC_Shorty_Backend::registerUrl_google ( $id, $relay ); - case 'isgd': return OC_Shorty_Backend::registerUrl_isgd ( $id, $relay ); - case 'tinyurl': return OC_Shorty_Backend::registerUrl_tinyurl ( $id, $relay ); - case 'tinycc': return OC_Shorty_Backend::registerUrl_tinycc ( $id, $relay ); - } // switch - } // try - catch (OC_Shorty_Exception $e) - { - throw $e; - } // catch - catch (Exception $e) - { - throw new OC_Shorty_Exception ( "Failed to register url '%s' at '%s' backend", array($relay,$type) ); - } // catch - } // OC_Shorty_Backend::registerUrl - - /** - * @method OC_Shorty_Backend::registerUrl_default - * @brief Pseudo-registers a given local relay url - * @param id (string) - * @param relay (url) - * @returns validated and pseudo-registered relay - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_default ( $id, $relay ) - { - return OC_Shorty_Type::validate ( $relay, OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_default - - /** - * @method OC_Shorty_Backend::registerUrl_static - * @brief Registers a given local relay url as local static shorty - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_static ( $id, $relay ) - { - if ( (FALSE===($base=trim ( OCP\Config::getAppValue('shorty','backend-static-base',FALSE)))) - ||(empty($base)) ) - throw new OC_Shorty_Exception ( 'No base url defined for the static backend' ); - return OC_Shorty_Type::validate ( $base.$id, OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_static - - /** - * @method OC_Shorty_Backend::registerUrl_bitly - * @brief Registers a given local relay url at the bit.ly shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_bitly ( $id, $relay ) - { - $bitly_api_user = OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-bitly-user',''); - $bitly_api_key = OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-bitly-key', ''); - if ( ! $bitly_api_key || ! $bitly_api_user ) - throw new OC_Shorty_Exception ( 'No API user or key configured' ); - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, 'https://api-ssl.bit.ly/shorten' ); - curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, TRUE ); - curl_setopt ( $curl, CURLOPT_POST, TRUE ); - curl_setopt ( $curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json') ); - curl_setopt ( $curl, CURLOPT_POSTFIELDS, json_encode(array('version'=>'2.0.1', - 'longUrl'=>$relay, - 'format'=>'json', - 'login'=>$bitly_api_user, - 'apiKey'=>$bitly_api_key) ) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||(NULL===($payload=json_decode($reply))) - ||(!is_object($payload)) - ||(!property_exists($payload,'id')) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'static'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $payload->id, OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_bitly - - /** - * @method OC_Shorty_Backend::registerUrl_cligs - * @brief Registers a given local relay url at the cli.gs shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_cligs ( $id, $relay ) - { - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, sprintf('http://cli.gs/api/v2/cligs/create?url=%s&appid=owncloud_shorty&test=1', urlencode(trim($relay))) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||( ! preg_match( '/^(.+)$/', $reply, $match )) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'cli.gs'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $match[1], OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_cligs - - /** - * @method OC_Shorty_Backend::registerUrl_isgd - * @brief Registers a given local relay url at the is.gd shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_isgd ( $id, $relay ) - { - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, sprintf('http://is.gd/create.php?format=simple&url=%s', urlencode(trim($relay))) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||( ! preg_match( '/^(.+)$/', $reply, $match )) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'is.gd'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $match[1], OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_isgd - - /** - * @method OC_Shorty_Backend::registerUrl_google - * @brief Registers a given local relay url at the google shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_google ( $id, $relay ) - { - $api_key = OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-google-key',''); - if ( ! $api_key ) - throw new OC_Shorty_Exception ( 'No goo.gl API key configured' ); - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, 'https://www.googleapis.com/urlshortener/v1/url' ); - curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, TRUE ); - curl_setopt ( $curl, CURLOPT_POST, TRUE ); - curl_setopt ( $curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json') ); - curl_setopt ( $curl, CURLOPT_POSTFIELDS, json_encode(array('longUrl'=>$relay, - 'key'=>$api_key) ) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||(NULL===($payload=json_decode($reply))) - ||(!is_object($payload)) - ||(!property_exists($payload,'id')) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'goo.gl'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $payload->id, OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_google - - /** - * @method OC_Shorty_Backend::registerUrl_tinycc - * @brief Registers a given local relay url at the tiny.cc shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_tinycc ( $id, $relay ) - { - $api_user = OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-tinycc-user',''); - $api_key = OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-tinycc-key',''); - if ( ! $api_key || ! $api_user ) - throw new OC_Shorty_Exception ( 'No goo.gl API key configured' ); - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, 'http://tiny.cc/?c=shorten' ); - curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, TRUE ); - curl_setopt ( $curl, CURLOPT_POST, TRUE ); - curl_setopt ( $curl, CURLOPT_HEADER, TRUE ); - curl_setopt ( $curl, CURLOPT_POSTFIELDS, array('longUrl'=>$relay, - 'version'=>'2.0.3', - 'format'=>'json', - 'login'=>$api_user, - 'apiKey'=>$api_key) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||(NULL===($payload=json_decode($reply))) - ||(!is_object($payload)) - ||(!property_exists($payload,'id')) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'tiny.cc'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $payload->id, OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_google - - /** - * @method OC_Shorty_Backend::registerUrl_tinyurl - * @brief Registers a given local relay url at the tinyURL shortening service - * @param id (string) - * @param relay (url) - * @returns registered and validated relay url - * @access public - * @author Chrisian Reiner - */ - static function registerUrl_tinyurl ( $id, $relay ) - { - $curl = curl_init ( ); - curl_setopt ( $curl, CURLOPT_URL, sprintf('http://tinyurl.com/api-create.php?url=%s', urlencode(trim($relay))) ); - curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE ); - if ( (FALSE===($reply=curl_exec($curl))) - ||( ! preg_match( '/^(.+)$/', $reply, $match )) ) - { - throw new OC_Shorty_Exception ( "Failed to register url at backend 'tinyUrl'" ); - } - curl_close ( $curl ); - return OC_Shorty_Type::validate ( $match[1], OC_Shorty_Type::URL ); - } // OC_Shorty_Backend::registerUrl_tinyurl - -} // class OC_Shorty_Backend diff --git a/apps/shorty/lib/exception.php b/apps/shorty/lib/exception.php deleted file mode 100644 index daeb9d10a9..0000000000 --- a/apps/shorty/lib/exception.php +++ /dev/null @@ -1,162 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file lib/exception.php - * Application specific exception class - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Exception - * @brief Application specific exception class - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Exception extends Exception -{ - protected $phrase = ''; - protected $param = array ( ); - - /** - * @method OC_Shorty_Exception::__construct - * @brief: Constructs an exception based on a phrase and a set of parameters - * @param phrase (string) Human readable message that should be translatable - * @param param (array) Set of parameters to be used as sprintf arguments to fill the phrase - * @access public - * @author Christian Reiner - */ - public function __construct ( $phrase, $param=array() ) - { - if ( is_array($param) ) - $this->param = $param; - else $this->param = array($param); - $this->phrase = $phrase; -// $this->message = vsprintf ( $phrase, $this->params ); - Exception::__construct ( vsprintf($phrase,$this->param), 1 ); - } - - /** - * @method OC_Shorty_Exception::getTranslation - * @brief: Returns the translated message of the exception - * @returns (string) Translated message including the filled in set of arguments - * @access public - * @author Christian Reiner - */ - public function getTranslation ( ) - { - return OC_Shorty_L10n::t ( $this->phrase, $this->param ); - } - - /** - * @method OC_Shorty_Exception::JSONerror - * @brief Calls OCP\JSON::error with a pretty formated version of an exception - * @param e (exception) an exception object holding information - * @returns (json) OCP\JSON::error - * @access public - * @author Christian Reiner - */ - static function JSONerror ( $e ) - { - $title = OC_Shorty_L10n::t("Exception"); - switch ( get_class($e) ) - { - case 'OC_Shorty_Exception': - $message = $e->getTranslation(); - break; - case 'PDOException': - $message = sprintf ( OC_Shorty_L10n::t( "%s\nMessage(code): %s (%s)\nFile(line): %s (%s)\nInfo: %%s", - OC_Shorty_L10n::t("Exception (%s)", get_class($e)), - htmlspecialchars($e->getMessage()), - htmlspecialchars($e->getCode()), - htmlspecialchars($e->getFile()), - htmlspecialchars($e->getLine()) ), - (method_exists($e,'errorInfo') ? trim($e->errorInfo()) : '-/-') ); - break; - default: - if ( is_a($e,'Exception') ) - $message = OC_Shorty_L10n::t("Unexpected type of exception caught: %s", get_class($e)); - else $message = OC_Shorty_L10n::t("Unknown object of type caught: %s", get_class($e)); - } // switch - // swallow any accidential output generated by php notices and stuff to preserve a clean JSON reply structure - $output = trim ( OC_Shorty_Tools::ob_control(FALSE) ); - if ( $output ) - { - $message = "! Swallowing accidential output from ajax routines ! \n" - ."Please fix this ! Here is the first line: \n" - .substr ( $output, 0, strpos($output,"\n") ); - OCP\Util::writeLog( 'shorty', $message, OC_Log::WARN ); - } // output - // return a clean JSON error - return OCP\JSON::error ( array ( 'title' => $title, - 'message' => sprintf("%s: %s", $title, $message) ) ); - } // function error -} // class OC_Shorty_Exception - -/** - * @class OC_Shorty_HttpException - * @brief Application specific exception class: protocol layer - * @access public - * @author Christian Reiner - */ -class OC_Shorty_HttpException extends OC_Shorty_Exception -{ - - /** - * @method OC_Shorty_HttpException::__construct - * @brief: Constructs an exception based on a phrase and a set of parameters - * @param status (integer) Http status code - * @access public - * @author Christian Reiner - */ - public function __construct ( $status ) - { - if ( is_numeric($status) - && array_key_exists($status,OC_Shorty_Type::$HTTPCODE) ) - { - $status = intval($status); - $phrase = OC_Shorty_Type::$HTTPCODE[$status]; - } - else - { - $status = 400; - $phrase = OC_Shorty_Type::$HTTPCODE[400]; // "Bad Request" - } // switch - - // return http status code to client (browser) - if ( ! headers_sent() ) - { - header ( sprintf("HTTP/1.0 %s %s",$status,$phrase) ); - } - $tmpl = new OCP\Template("shorty", "tmpl_http_status", "guest"); - $tmpl->assign("explanation", OC_Shorty_L10n::t($phrase)); - $tmpl->printPage(); - exit; - } // function __construct - -} // class OC_Shorty_HttpException - -?> diff --git a/apps/shorty/lib/hooks.php b/apps/shorty/lib/hooks.php deleted file mode 100644 index 6ba59eccbd..0000000000 --- a/apps/shorty/lib/hooks.php +++ /dev/null @@ -1,64 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file lib/hooks.php - * Static class providing routines to populate hooks called by other parts of ownCloud - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Hooks - * @brief Static 'namespace' class for api hook population - * ownCloud propagates to use static classes as namespaces instead of OOP. - * This 'namespace' defines routines to populate hooks called by other parts of ownCloud - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Hooks -{ - /** - * @brief Deletes all Shortys and preferences of a certain user - * @param paramters (array) parameters from postDeleteUser-Hook - * @return bool - */ - public static function deleteUser ( $parameters ) - { - OCP\Util::writeLog ( 'user post delete','wiping all users Shortys', OCP\Util::INFO ); - $result = TRUE; - $param = array ( 'user' => OCP\User::getUser() ); - // wipe shortys - $query = OCP\DB::prepare ( OC_Shorty_Query::WIPE_SHORTYS ); - if ( FALSE===$query->execute($param) ) - $result = FALSE; - // wipe preferences - $query = OCP\DB::prepare ( OC_Shorty_Query::WIPE_PREFERENCES ); - if ( FALSE===$query->execute($param) ) - $result = FALSE; - // report completion success - return $result; - } -} diff --git a/apps/shorty/lib/l10n.php b/apps/shorty/lib/l10n.php deleted file mode 100644 index 648130645a..0000000000 --- a/apps/shorty/lib/l10n.php +++ /dev/null @@ -1,93 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file lib/l10n.php - * Translation singleton - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_L10n - * @brief Convenient translation singleton - * @access public - * @author Christian Reiner - */ -class OC_Shorty_L10n -{ - /** - * @var OC_Shorty_L10n::dictionary - * @brief An internal dictionary file filled from the translation files provided. - * @access private - * @author Christian Reiner - */ - private $dictionary; - - /** - * @var OC_Shorty_L10n::instance - * @brief Internal singleton object - * @access private - * @author Christian Reiner - */ - static private $instance=NULL; - - /** - * @method OC_Shorty_L10n::__construct - * @brief - * @access private - * @author Christian Reiner - */ - private function __construct ( ) { $this->dictionary = new OC_L10n('shorty'); } - - /** - * @method OC_Shorty_L10n::t - * @brief Translates a given string into the users session language and fills any placeolders - * @param phrase to be translated - * @param … further arguments used as filling tokens in the tradition of printf strategies - * @returns translated phrase or the original phrase incase no translation could be found - * @access public - * @author Christian Reiner - */ - static public function t ( $phrase ) - { - // create singleton instance, if required - if ( ! self::$instance ) - self::$instance = new OC_Shorty_L10n ( ); - // handle different styles of how arguments can be handed over to this method - switch ( func_num_args() ) - { - case 1: return self::$instance->dictionary->t ( $phrase, array() ); - case 2: $arg = func_get_arg(1); - if ( is_array($arg) ) - return self::$instance->dictionary->t ( $phrase, $arg ); - else return self::$instance->dictionary->t ( $phrase, array($arg) ); - default: $args = func_get_args(); - array_shift ( $args ); - return self::$instance->dictionary->t ( $phrase, $args ); - } - } -} // class OC_Shorty_L10n -?> diff --git a/apps/shorty/lib/meta.php b/apps/shorty/lib/meta.php deleted file mode 100644 index 91937bd3c8..0000000000 --- a/apps/shorty/lib/meta.php +++ /dev/null @@ -1,213 +0,0 @@ - -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see . -* -*/ - -/** - * @file lib/meta.php - * Routines to retrieve meta information about a remote url - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Meta - * @brief Static 'namespace' class for url meta information retrieval - * ownCloud propagates to use static classes as namespaces instead of OOP. - * This 'namespace' defines routines for the retrieval of meta information about remote urls. - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Meta -{ - - /** - * @method OC_Shorty_Meta::fetchMetaData - * @brief Retrieves the meta information to a given remote url - * @param url decoded target url for which meta information if requested - * @returns associative array holding the requested meta data - * @access public - * @author Christian Reiner - */ - static function fetchMetaData ( $url ) - { - $url_token = parse_url ( $url ); - // some sane fallback values, in case we cannot get the meta data - $meta = array(); - $meta['target'] = $url; - $meta['title'] = strtolower ( $url_token['host'] ); - $meta['scheme'] = strtolower ( $url_token['scheme'] ); - $meta['mimetype'] = 'application/octet-stream'; - $meta['schemicon'] = self::selectIcon ( 'scheme', strtolower($url_token['scheme']) ); - // we wont bother retrieving data about other protocols than http or ftp - if ( ! in_array(strtolower($url_token['scheme']),array('http','https','ftp','ftps')) ) - return $meta; - // to fetch meta data we rely on curl being installed - if ( ! function_exists('curl_init') ) - return $meta; - // try to retrieve the meta data - $handle = curl_init ( ); - curl_setopt ( $handle, CURLOPT_URL, $url ); - curl_setopt ( $handle, CURLOPT_RETURNTRANSFER, 1 ); - curl_setopt ( $handle, CURLOPT_FOLLOWLOCATION, TRUE ); - curl_setopt ( $handle, CURLOPT_MAXREDIRS, 10 ); - if ( FALSE!==($page=curl_exec($handle)) ) - { - // try to extract title from page - preg_match ( "/.*(.*)<\/title>.*<\/head>/si", $page, $match ); - $meta['title'] = htmlspecialchars_decode ( $match[1] ); - $meta['staticon'] = self::selectIcon ( 'state', TRUE ); - // final url after a possible redirection - $meta['final'] = curl_getinfo ( $handle, CURLINFO_EFFECTIVE_URL ); - // try to extract favicon from page - preg_match ( '/<[^>]*link[^>]*(rel=["\']icon["\']|rel=["\']shortcut icon["\']) .*href=["\']([^>]*)["\'].*>/iU', $page, $match ); - if (1<sizeof($match)) - { - // the specified uri might be an url, an absolute or a relative path - // we have to turn it into an url to be able to display it out of context - $favicon = htmlspecialchars_decode ( $match[2] ); - // test for an url - if (parse_url($favicon,PHP_URL_SCHEME)) - { - $meta['favicon'] = $favicon; - } - // test for an absolute path - elseif ( 0===strpos(parse_url($favicon,PHP_URL_PATH),'/') ) - { - $url_token = parse_url($meta['final']); - $meta['favicon'] = sprintf( '%s://%s/%s', $url_token['scheme'], $url_token['host'], $favicon ); - } - // so it appears to be a relative path - else - { - $url_token = parse_url($meta['final']); - $meta['favicon'] = sprintf( '%s://%s%s%s', $url_token['scheme'], $url_token['host'], dirname($url_token['path']), $favicon ); - } - } - $meta['mimetype'] = preg_replace ( '/^([^;]+);.*/i', '$1', curl_getinfo($handle,CURLINFO_CONTENT_TYPE) ); - $meta['mimicon'] = self::selectIcon ( 'mimetype', $meta['mimetype'] ); - $meta['code'] = curl_getinfo ( $handle, CURLINFO_HTTP_CODE ); - $meta['status'] = OC_Shorty_L10n::t ( self::selectCode('status',$meta['code']) ); - $meta['explanation'] = OC_Shorty_L10n::t ( self::selectCode('explanation',$meta['code']) ); - } - curl_close ( $handle ); - // that's it ! - return $meta; - } // function fetchMetaData - - /** - * @method OC_Shorty_Meta::selectCode - * @brief Some helper utility used to resolve numeric http status codes into human readable strings - * @param aspect a string indicating a section/pool a code is to be resolved in - * @param identifier a string indicating a specific code to be resolved - * @returns a human readable string resolving the specified numeric status code - * @throws OC_Shorty_Exception in case of an undefined code to be resolved - * @access public - * @author Christian Reiner - */ - static function selectCode ( $aspect, $identifier ) - { - // map of official http status codes - $_code_map = array - ( - 'status' => OC_Shorty_Type::$HTTPCODE, - 'explanation' => array - ( - 200 => 'Target url is valid and resolved.', - 201 => 'The request has been fulfilled and created a new ressource.', - 202 => 'The request has been accepted.', - 203 => 'The request yielded in non-authorative information.', - 204 => 'The request has been fulfilled but not produced any content.', - 205 => 'The request has been fulfilled and the view should be reset.', - 206 => 'The request has been fulfilled partially.', - ) - ); - // resolve specified code against map or provide some fallback content - if ( key_exists($aspect,$_code_map) && key_exists($identifier,$_code_map[$aspect]) ) - return $_code_map[$aspect][$identifier]; - else - { - switch ( $aspect ) - { - case 'status': return sprintf("Status %s [unknown]",$identifier); - case 'explanation': return sprintf("[Undefined status code '%s']",$identifier); - default: throw new OC_Shorty_Exception ( "unknown aspect '%s' requested to resolve code '%s'", - array($aspect,$identifier) ); - } // switch - } - } // function selectCode - - /** - * @method OC_Shorty_Meta::selectIcon - * @brief Some helper utility for the easy integrate of icon references into templates and alike - * @param aspect a string indicating a section/pool an icon is to be chosen from - * @param identifier a string indicating a specific icon to be referenced - * @returns a hyper reference to an icon in form of a string - * @access public - * @author Christian Reiner - */ - static function selectIcon ( $aspect, $identifier ) - { - switch ( $aspect ) - { - case 'state': - switch ($identifier) - { - case TRUE: return OCP\Util::imagePath('shorty', 'status/good.png'); - case FALSE: return OCP\Util::imagePath('shorty', 'status/bad.png'); - default: return OCP\Util::imagePath('shorty', 'status/neutral.png'); - } // switch identifier - case 'scheme': - switch ($identifier) - { - case 'http': - case 'https': return OCP\Util::imagePath('shorty', 'scheme/H.png'); - case 'ftp': - case 'ftps': return OCP\Util::imagePath('shorty', 'scheme/F.png'); - case 'sftp': return OCP\Util::imagePath('shorty', 'scheme/S.png'); - case 'mailto': return OCP\Util::imagePath('shorty', 'scheme/M.png'); - case 'gopher': return OCP\Util::imagePath('shorty', 'scheme/G.png'); - case 'webdav': - case 'webdavs': return OCP\Util::imagePath('shorty', 'scheme/W.png'); - default: return OCP\Util::imagePath('shorty', 'blank.png'); - } // switch identifier - case 'mimetype': - $identifier = explode('/',$identifier); - switch ($identifier[0]) - { - case 'audio': return OCP\Util::imagePath('core', 'filetypes/audio.png'); - case 'text': return OCP\Util::imagePath('core', 'filetypes/text.png'); - case 'video': return OCP\Util::imagePath('core', 'filetypes/video.png'); - case 'application': - switch ($identifier[1]) - { - case 'pdf': return OCP\Util::imagePath('core', 'filetypes/application-pdf.png'); - default: return OCP\Util::imagePath('shorty', 'blank.png'); - } // switch identifier[1] - default: return OCP\Util::imagePath('shorty', 'blank.png'); - } // switch identifier[0] - } // switch aspect - } // function selectIcon - -} // class OC_Shorty_Meta -?> diff --git a/apps/shorty/lib/query.php b/apps/shorty/lib/query.php deleted file mode 100644 index 6501a54d92..0000000000 --- a/apps/shorty/lib/query.php +++ /dev/null @@ -1,57 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file lib/query.php - * Static catalog of sql queries - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Query - * @brief Static catalog of sql queries - * These query templates are referenced by a OC_Shorty_Query::URL_... - * They have to be prapared by adding an array of parameters - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Query -{ - const URL_INSERT = "INSERT INTO *PREFIX*shorty (id,status,favicon,title,source,target,user,until,created,notes) VALUES (:id,:status,:favicon,:title,:source,:target,:user,:until,CURRENT_DATE,:notes)"; - const URL_DELETE = "DELETE FROM *PREFIX*shorty WHERE user=:user AND id=:id"; - const URL_REMOVE = "DELETE FROM *PREFIX*shorty WHERE user=:user AND 'deleted'=status"; - const URL_UPDATE = "UPDATE *PREFIX*shorty SET status=:status,title=:title,until=:until,notes=:notes WHERE user=:user AND id=:id"; - const URL_STATUS = "UPDATE *PREFIX*shorty SET status=:status WHERE user=:user AND id=:id"; - const URL_CLICK = "UPDATE *PREFIX*shorty SET accessed=CURRENT_TIMESTAMP, clicks=(clicks+1) WHERE id=:id"; - const URL_FORWARD = "SELECT user,source,target,status,(until IS NOT NULL AND until!='' AND until<CURRENT_TIMESTAMP) AS expired FROM *PREFIX*shorty WHERE id=:id"; - const URL_SOURCE = "SELECT id,source,target,status,(until IS NOT NULL AND until!='' AND until<CURRENT_TIMESTAMP) AS expired FROM *PREFIX*shorty WHERE source=:source"; - const URL_VERIFY = "SELECT id,status,favicon,title,source,target,clicks,created,accessed,until,notes FROM *PREFIX*shorty WHERE user=:user AND id=:id LIMIT 1"; - const URL_LIST = "SELECT id,status,favicon,title,source,target,clicks,created,accessed,until,notes FROM *PREFIX*shorty WHERE user=:user ORDER BY :sort"; - const URL_COUNT = "SELECT count(*) AS sum_shortys,IFNULL(sum(clicks),0) AS sum_clicks FROM *PREFIX*shorty WHERE user=:user"; - const WIPE_SHORTYS = "DELETE FROM *PREFIX*shorty WHERE user=:user"; - const WIPE_PREFERENCES = "DELETE FROM *PREFIX*preferences WHERE user=:user"; -} // class OC_Shorty_Query -?> diff --git a/apps/shorty/lib/tools.php b/apps/shorty/lib/tools.php deleted file mode 100644 index 2b3bac7067..0000000000 --- a/apps/shorty/lib/tools.php +++ /dev/null @@ -1,235 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file lib/tools.php - * A collection of general utility routines - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Tools - * @brief Collection of a few practical routines, a tool box - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Tools -{ - // internal flag indicating if output buffering should be used to prevent accidentially output during ajax requests - static $ob_usage = TRUE; - // internal flag indicating if there is currently an output buffer active - static $ob_active = FALSE; - - /** - * @method OC_Shorty_Tools::ob_control - * @param on (boolean) wether to activate or deactivate the buffer - * @access public - * @author Christian Reiner - */ - static function ob_control ( $on=TRUE ) - { - $output = NULL; - if ( self::$ob_usage ) - { - // attempt to use outpout buffering - if ( $on ) - { - // start buffering if possible and not yet started before - if ( function_exists('ob_start') // output buffers installed at all ? - && ! self::$ob_active ) // don't stack buffers (create buffer only, if not yet started) - { - ob_implicit_flush ( FALSE ); - ob_start ( ); - self::$ob_active = TRUE; - } - } // if $on==TRUE - else - { - // end buffering _if_ it has been started before - if ( self::$ob_active ) - { - $output = ob_get_contents ( ); - ob_end_clean ( ); - self::$ob_active = FALSE; - } - } // if $on==FALSE - } // if ob_usage - return $output; - } // function ob_control - - /** - * @method OC_Shorty_Tools::db_escape - * @brief escape a value for incusion in db statements - * @param value (string) value to be escaped - * @returns (string) escaped string value - * @throws OC_Shorty_Exception in case of an unknown database engine - * @access public - * @author Christian Reiner - * @todo use mdb2::quote() / mdb2:.escape() instead ? - */ - static function db_escape ( $value ) - { - $type = OCP\Config::getSystemValue ( 'dbtype', 'sqlite' ); - switch ( $type ) - { - case 'sqlite': - case 'sqlite3': - return sqlite_escape_string ( $value ); - case 'pgsql': - return pg_escape_string ( $value ); - case 'mysql': - if (get_magic_quotes_gpc()) - return mysql_real_escape_string ( stripslashes($value) ); - else return mysql_real_escape_string ( $value ); - } - throw new OC_Shorty_Exception ( "unknown database backend type '%1'", array($type) ); - } // function db_escape - - /** - * @method OC_Shorty_Tools::db_timestamp - * @brief current timestamp as required by db engine - * @returns (string) current timestamp as required by db engine - * @throws OC_Shorty_Exception in case of an unknown database engine - * @access public - * @author Christian Reiner - * @todo not really required any more, we rely on CURRENT_TIMESTAMP instead - */ - static function db_timestamp ( ) - { - $type = OCP\Config::getSystemValue( "dbtype", "sqlite" ); - switch ( $type ) - { - case 'sqlite': - case 'sqlite3': return "strftime('%s','now')"; - case 'mysql': return 'UNIX_TIMESTAMP()'; - case 'pgsql': return "date_part('epoch',now())::integer"; - } - throw new OC_Shorty_Exception ( "unknown database backend type '%1'", array($type) ); - } // function db_timestamp - - /** - * @method OC_Shorty_Tools::shorty_id - * @brief Creates a unique id to be used for a new shorty entry - * @returns (string) valid and unique id - * @access public - * @author Christian Reiner - */ - static function shorty_id ( ) - { - // each shorty installation uses a (once self generated) 62 char alphabet - $alphabet=OCP\Config::getAppValue('shorty','id-alphabet'); - if ( empty($alphabet) ) - { - $alphabet = self::randomAlphabet(62); - OCP\Config::setAppValue ( 'shorty', 'id-alphabet', $alphabet ); - } - // use alphabet to generate a id being unique over time - return self::convertToAlphabet ( str_replace(array(' ','.'),'',microtime()), $alphabet ); - } // function shorty_id - - /** - * - */ - static function randomAlphabet ($length) - { - if ( ! is_integer($length) ) - return FALSE; - $c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxwz0123456789"; - for($l=0;$l<$length;$l++) $s .= $c{rand(0,strlen($c))}; - return str_shuffle($s); - } // function randomAlphabet - - /** - * @method OC_Shorty_Tools::convertToAlphabet - * @brief Converts a given decimal number into an arbitrary base (alphabet) - * @param number decimal value to be converted - * @returns (string) converted value in string notation - * @access public - * @author Christian Reiner - */ - static function convertToAlphabet ( $number, $alphabet ) - { - $alphabetLen = strlen($alphabet); - $decVal = (int) $number; - $number = FALSE; - $nslen = 0; - $pos = 1; - while ($decVal > 0) - { - $valPerChar = pow($alphabetLen, $pos); - $curChar = floor($decVal / $valPerChar); - if ($curChar >= $alphabetLen) - { - $pos++; - } else { - $decVal -= ($curChar * $valPerChar); - if ($number === FALSE) - { - $number = str_repeat($alphabet{1}, $pos); - $nslen = $pos; - } - $number = substr($number, 0, ($nslen - $pos)) . $alphabet{$curChar} . substr($number, (($nslen - $pos) + 1)); - $pos--; - } - } - if ($number === FALSE) $number = $alphabet{1}; - return $number; - } - - /** - * @method OC_Shorty_Tools::relayUrl - * @brief Generates a relay url for a given id acting as a href target for all backends - * @param id (string) shorty id as shorty identification - * @returns (string) generated absolute relay url - * @access public - * @author Christian Reiner - */ - static function relayUrl ($id) - { - return sprintf ( '%s?service=%s&id=%s', OCP\Util::linkToAbsolute("", "public.php"), 'shorty_relay', $id ); - } // function relayUrl - - /** - * @method OC_Shorty_Tools::countShortys - * @brief Returns the total number of entries and clicks from the database - * @returns (array) two elements sum_shortys & sum_clicks holding an integer each - * @access public - * @author Christian Reiner - */ - static function countShorties () - { - $param = array - ( - ':user' => OCP\User::getUser ( ), - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_COUNT ); - $result = $query->execute($param); - $reply = $result->fetchAll(); - return $reply[0]; - } // function countShorties - -} // class OC_Shorty_Tools -?> diff --git a/apps/shorty/lib/type.php b/apps/shorty/lib/type.php deleted file mode 100644 index 97cbf04ddb..0000000000 --- a/apps/shorty/lib/type.php +++ /dev/null @@ -1,291 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file lib/type.php - * Type handling, recognition and verification routines - * @author Christian Reiner - */ - -/** - * @class OC_Shorty_Type - * @brief Static 'namespace' class offering routines and constants used to handle type recognition and value verification - * @access public - * @author Christian Reiner - */ -class OC_Shorty_Type -{ - // the 'types' of values we deal with, actually more something like flavours - const ID = 'id'; - const STATUS = 'status'; - const SORTKEY = 'sortkey'; - const SORTVAL = 'sortval'; - const STRING = 'string'; - const URL = 'url'; - const INTEGER = 'integer'; - const FLOAT = 'float'; - const DATE = 'date'; - const TIMESTAMP = 'timestamp'; - // a list of all valid list sorting codes - static $SORTING = array ( - '' =>'created DESC', // default - 'aa'=>'accessed', 'ad'=>'accessed DESC', - 'ca'=>'created', 'cd'=>'created DESC', - 'da'=>'until', 'dd'=>'until DESC', - 'ha'=>'clicks', 'hd'=>'clicks DESC', - 'ka'=>'id', 'kd'=>'id DESC', - 'sa'=>'status', 'sd'=>'status DESC', - 'ta'=>'title', 'td'=>'title DESC', - 'ua'=>'target', 'ud'=>'target DESC' ); - // a list of all valid user preferences - static $PREFERENCE = array ( - 'backend-type' => OC_Shorty_Type::STRING, - 'backend-static-base' => OC_Shorty_Type::URL, - 'backend-bitly-user' => OC_Shorty_Type::STRING, - 'backend-bitly-key' => OC_Shorty_Type::STRING, - 'backend-google-key' => OC_Shorty_Type::STRING, - 'backend-tinycc-user' => OC_Shorty_Type::STRING, - 'backend-tinycc-key' => OC_Shorty_Type::STRING, - 'sms-control' => OC_Shorty_Type::STRING, - 'list-sort-code' => OC_Shorty_Type::SORTKEY, - ); - // valid status for entries - static $STATUS = array ( - 'blocked', - 'private', - 'shared', - 'public', - 'deleted', - ); - // a list of implemented backends - static $BACKENDS = array ( - 'none' => ' [ none ] ', - 'static' => 'static backend', -// 'bitly' => 'bitly.com service', -// 'cligs' => 'cli.gs service', - 'isgd' => 'is.gd service', - 'google' => 'goo.gl service', -// 'tinycc' => 'tiny.cc service', - 'tinyurl' => 'ti.ny service', - ); - // a list of all valid system settings - static $SETTING = array ( - 'backend-static-base' => OC_Shorty_Type::URL, - ); - static $HTTPCODE = array ( - 200 => 'Ok', - 201 => 'Created', - 202 => 'Accepted', - 203 => 'Non-Authoritative Information', - 204 => 'No Content', - 205 => 'Reset Content', - 206 => 'Partial Content', - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => '(unused)', - 307 => 'Temporary Redirect', - 400 => 'Bad Request', - 401 => 'Unauthorized', - 402 => 'Payment Required', - 403 => 'Forbidden', - 404 => 'Not Found', - 405 => 'Method Not Allowed', - 406 => 'Not Acceptable', - 407 => 'Proxy Authentication Required', - 408 => 'Request Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - ); - - /** - * @method OC_Shorty_Type::validate - * @brief Validates a given value against a type specific regular expression - * Validates a given value according to the claimed type of the value. - * Validation is done by matching the value against a type specific regular expression. - * @param value the value to be verified according to the specified type - * @param type the type the value is said to belong to, important for verification - * @param strict flag indicating if the verification should be done strict, that is if an exception should be thrown in case of a failure - * @returns the value itself in case of a positive validation, NULL or an exception in case of a failure, depending on the flag indication strict mode - * @throws error indicating a failed validation in case of strict mode - * @access public - * @author Christian Reiner - */ - static function validate ( $value, $type, $strict=FALSE ) - { - switch ( $type ) - { - case self::ID: - if ( preg_match ( '/^[a-z0-9]{2,20}$/i', $value ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::STATUS: - if ( in_array($value,OC_Shorty_Type::$STATUS) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::SORTKEY: - if ( array_key_exists ( trim($value), self::$SORTING ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::SORTVAL: - if ( in_array ( trim($value), self::$SORTING ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::STRING: - if ( preg_match ( '/^.*$/x', str_replace("\n","\\n",$value) ) ) - return str_replace("\n","\\n",$value); - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::URL: -// $pattern = '/^([a-zA-Z][a-zA-Z][a-zA-Z0-9]+)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\;\:\,\@\?\'\\\+&%\$#\=~_\-]+)?)*$/'; - $pattern = '/^([a-zA-Z][a-zA-Z][a-zA-Z0-9]+)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(\/($|.+)?)*$/'; - if ( preg_match ( $pattern, $value ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::INTEGER: - if ( preg_match ( '/^[0-9]+$/', $value ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::FLOAT: - if ( preg_match ( '/^[0-9]+(\.[0-9]+)?$/', $value ) ) - return $value; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::TIMESTAMP: - if ( preg_match ( '/^[0-9]{10}$/', $value ) ) - return $value; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - case self::DATE: - if (FALSE!==($time=strtotime($value))) - return $time; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "invalid value '%s' for type '%s'", array( ((24<sizeof($value))?$value:substr($value,0,21).'…'),$type) ); - } // switch $type - throw new OC_Shorty_Exception ( "unknown request argument type '%s'", array($type) ); - } // function is_valid - - /** - * @method OC_Shorty_Type::normalize - * @brief cleanup and formal normalization of a given value according to its type - * Normalizes a given value according to its claimed type. - * This typically means trimming of string values, but sometimes also more specific actions. - * @param value the value to be normalized - * @param type the supposed type of the value - * @param strict boolean flag indicating if the normalization should be done in a strict way - * @returns the normalized value - * @throws error indicating a parameter violation - * @access public - * @author Christian Reiner - */ - static function normalize ( $value, $type, $strict=FALSE ) - { - if (NULL===(self::validate($value,$type,$strict))) - { - if ( ! $strict) - return NULL; - else - throw new OC_Shorty_Exception ( "invalid value '%1\$s' for type '%2\$s'", array($value,$type) ); - } // if - switch ( $type ) - { - case self::ID: return trim ( $value ); - case self::STATUS: return trim ( $value ); - case self::SORTKEY: return trim ( $value ); - case self::SORTVAL: return trim ( $value ); - case self::STRING: return trim ( $value ); - case self::URL: return trim ( $value ); - case self::INTEGER: return sprintf ( '%d', $value ); - case self::FLOAT: return sprintf ( '%f', $value ); - case self::TIMESTAMP: return trim ( $value ); - case self::DATE: return date ( 'Y-m-d', self::validate($value,OC_Shorty_Type::DATE) ); - } // switch $type - throw new OC_Shorty_Exception ( "unknown request argument type '%s'", array($type) ); - } // function normalize - - /** - * @method OC_Shorty_Type::req_argument - * @brief returns checked request argument or throws an error - * @param arg (string) name of the request argument to get_argument - * @param strict (bool) controls if an exception will be thrown upon a missing argument - * @returns (string) checked and prepared value of request argument - * @throws error indicating a parameter violation - * @access public - * @author Christian Reiner - */ - static function req_argument ( $arg, $type, $strict=FALSE ) - { - switch ( $_SERVER['REQUEST_METHOD'] ) - { - case 'POST': - if ( isset($_POST[$arg]) && !empty($_POST[$arg]) ) - return self::normalize ( urldecode($_POST[$arg]), $type ) ; - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "missing mandatory argument '%1s'", array($arg) ); - case 'GET': - if ( isset($_GET[$arg]) && !empty($_GET[$arg]) ) - return self::normalize ( urldecode(trim($_GET[$arg])), $type, $strict ); - elseif ( ! $strict) - return NULL; - throw new OC_Shorty_Exception ( "missing mandatory argument '%1s'", array($arg) ); - default: - throw new OC_Shorty_Exception ( "unexpected http request method '%1s'", array($_SERVER['REQUEST_METHOD']) ); - } - } // function req_argument - -} // class OC_Shorty_Query -?> diff --git a/apps/shorty/preferences.php b/apps/shorty/preferences.php deleted file mode 100644 index 6e122fe410..0000000000 --- a/apps/shorty/preferences.php +++ /dev/null @@ -1,68 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file settings.php - * This plugins user preferences dialog - * The dialog will be included in the general framework of the user preferences page - * @access public - * @author Christian Reiner - */ - -OCP\Util::addStyle ( '3rdparty', 'chosen/chosen' ); -OCP\Util::addStyle ( 'shorty', 'shorty' ); -OCP\Util::addStyle ( 'shorty', 'preferences' ); - -OCP\Util::addScript ( '3rdparty', 'chosen/chosen.jquery.min' ); -OCP\Util::addScript ( 'shorty', 'shorty' ); -OCP\Util::addScript ( 'shorty', 'preferences' ); -if ( OC_Log::DEBUG==OC_Config::getValue( "loglevel", OC_Log::WARN ) ) - OCP\Util::addScript ( 'shorty', 'debug' ); - - -// fetch template -$tmpl = new OCP\Template ( 'shorty', 'tmpl_preferences' ); -// inflate template -$backend_types = OC_Shorty_Type::$BACKENDS; -// kick out static option again if no global backend base has been specified in the system settings -$backend_static_base = OCP\Config::getAppValue('shorty','backend-static-base',''); -if ( empty($backend_static_base) - || !parse_url($backend_static_base,PHP_URL_SCHEME) - || !parse_url($backend_static_base,PHP_URL_HOST) ) - unset($backend_types['static']); -// feed template engine -$tmpl->assign ( 'backend-types', $backend_types ); -$tmpl->assign ( 'backend-static-base', $backend_static_base ); -$tmpl->assign ( 'backend-bitly-user', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-bitly-user','') ); -$tmpl->assign ( 'backend-bitly-key', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-bitly-key','') ); -$tmpl->assign ( 'backend-google-key', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-google-key','') ); -$tmpl->assign ( 'backend-tinycc-user', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-tinycc-user','') ); -$tmpl->assign ( 'backend-tinycc-key', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-tinycc-key','') ); -$tmpl->assign ( 'backend-type', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','backend-type','') ); -$tmpl->assign ( 'sms-control', OCP\Config::getUserValue(OCP\User::getUser(),'shorty','sms-control','disabled') ); -// render template -return $tmpl->fetchPage ( ); -?> diff --git a/apps/shorty/qrcode.php b/apps/shorty/qrcode.php deleted file mode 100644 index 43b91b22af..0000000000 --- a/apps/shorty/qrcode.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file qrcode.php - * Generates qr code barcodes cading a specified url - * @access public - * @author Christian Reiner - */ - -require_once ( '3rdparty/php/phpqrcode.php' ); - -$source = NULL; -// we try to guess what the request indicates: -// - a (source) url to be looked up in the database -foreach ($_GET as $key=>$val) // in case there are unexpected, additional arguments like a timestamp added by some stupid proxy -{ - switch ($key) - { - default: - // unrecognized key, we ignore it - break; - case 'url': - case 'uri': - case 'ref': - case 'source': - case 'target': - // a recognized argument key indicating an id to be looked up - $source = OC_Shorty_Type::req_argument($key,OC_Shorty_Type::URL,FALSE); - break 2; // skip switch AND foreach - } // switch -} // foreach - -// generate qr code for the specified url, IF it exists and is usable in the database -try -{ - if ( $source ) - { - $param = array ( 'source' => OC_Shorty_Type::normalize($source,OC_Shorty_Type::URL) ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_SOURCE ); - $result = $query->execute($param)->FetchAll(); - - if ( FALSE===$result ) - throw new OC_Shorty_HttpException ( 500 ); - elseif ( ! is_array($result) ) - throw new OC_Shorty_HttpException ( 500 ); - elseif ( 0==sizeof($result) ) - { - // no entry found => 404: Not Found - throw new OC_Shorty_HttpException ( 404 ); - } - elseif ( 1<sizeof($result) ) - { - // multiple matches => 409: Conflict - throw new OC_Shorty_HttpException ( 409 ); - } - elseif ( (!array_key_exists(0,$result)) || (!is_array($result[0])) || (!array_key_exists('source',$result[0])) ) - { - // invalid entry => 500: Internal Server Error - throw new OC_Shorty_HttpException ( 500 ); - } - elseif ( (!array_key_exists('source',$result[0])) || ('1'==$result[0]['expired']) ) - { - // entry expired => 410: Gone - throw new OC_Shorty_HttpException ( 410 ); - } - // generate qrcode, regardless of who sends the request - QRcode::png ( $source ); - } // if $source - else - { - // refuse forwarding => 403: Forbidden - throw new OC_Shorty_HttpException ( 403 ); - } -} catch ( OC_Shorty_Exception $e ) { header($e->getMessage()); } - -?> diff --git a/apps/shorty/relay.php b/apps/shorty/relay.php deleted file mode 100644 index 077a3625af..0000000000 --- a/apps/shorty/relay.php +++ /dev/null @@ -1,140 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file relay.php - * This is the plugins central relaying feature - * All relay requests are handled by this file. - * @access public - * @author Christian Reiner - */ - -OCP\App::setActiveNavigationEntry ( 'shorty_index' ); - -$arg = NULL; -// we try to guess what the request indicates: -// - a (shorty) id to be looked up in the database resulting in a forwarding to the stored target -// - a (target) url to be added as a new shorty -// - none of the two, so just a plain list of existing shortys -foreach ($_GET as $key=>$val) // in case there are unexpected, additional arguments like a timestamp added by some stupid proxy -{ - switch ($key) - { - default: - // unrecognized key, we ignore it - break; - case 'id': - case 'shorty': - case 'ref': - case 'entry': - // a recognized argument key indicating an id to be looked up - $arg = OC_Shorty_Type::req_argument($key,OC_Shorty_Type::ID,FALSE); - break 2; // skip switch AND foreach - } // switch -} // foreach - -// an id was specified, ordinary or special meaning ? -if ( '0000000000'==$arg ) -{ - // this is a pseudo id, used to test the setup, so just return a positive message. - // this is used to test the setup of the static backend, shorty calls itself from there - OCP\Util::writeLog( 'shorty', "Positiv validation of static backend base url", OC_Log::INFO ); - OCP\JSON::success ( array ( ) ); - exit(); -} - -// now construct the target url and relay to it (if applicable) -try -{ - // detect requested shorty id from request - $p_id = trim ( OC_Shorty_Type::normalize($arg,OC_Shorty_Type::ID) ) ; - if ( $p_id ) - { - $param = array - ( - 'id' => $p_id, - ); - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_FORWARD ); - $result = $query->execute($param)->FetchAll(); - if ( FALSE===$result ) - throw new OC_Shorty_HttpException ( 500 ); - elseif ( ! is_array($result) ) - throw new OC_Shorty_HttpException ( 500 ); - elseif ( 0==sizeof($result) ) - { - // no entry found => 404: Not Found - throw new OC_Shorty_HttpException ( 404 ); - } - elseif ( 1<sizeof($result) ) - { - // multiple matches => 409: Conflict - throw new OC_Shorty_HttpException ( 409 ); - } - elseif ( (!array_key_exists(0,$result)) || (!is_array($result[0])) || (!array_key_exists('target',$result[0])) ) - { - // invalid entry => 500: Internal Server Error - throw new OC_Shorty_HttpException ( 500 ); - } - elseif ( (!array_key_exists('target',$result[0])) || ('1'==$result[0]['expired']) ) - { - // entry expired => 410: Gone - throw new OC_Shorty_HttpException ( 410 ); - } - // an usable target ! - $target = trim($result[0]['target']); - // check status of matched entry - switch (trim($result[0]['status'])) - { - default: - case 'blocked': - // refuse forwarding => 403: Forbidden - throw new OC_Shorty_HttpException ( 403 ); - case 'private': - // check if user owns the Shorty, deny access if not - if ( $result[0]['user']!=OCP\User::getUser() ) - // refuse forwarding => 403: Forbidden - throw new OC_Shorty_HttpException ( 403 ); - // NO break; but fall through to the action in 'case public:' - case 'shared': - // check if we are a user, deny access if not - if ( ! OCP\User::isLoggedIn() ) - // refuse forwarding => 403: Forbidden - throw new OC_Shorty_HttpException ( 403 ); - // NO break; but fall through to the action in 'case public:' - case 'public': - // forward to target, regardless of who sends the request - header("HTTP/1.0 301 Moved Permanently"); - // http forwarding header - header ( sprintf('Location: %s', $target) ); - } // switch status - // register click in shorty - $query = OCP\DB::prepare ( OC_Shorty_Query::URL_CLICK ); - $query->execute ( $param ); - exit(); - } // if id -} catch ( OC_Shorty_Exception $e ) { header($e->getMessage()); } - -?> diff --git a/apps/shorty/settings.php b/apps/shorty/settings.php deleted file mode 100644 index f10e354a7b..0000000000 --- a/apps/shorty/settings.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * @file settings.php - * This plugins system settings dialog - * The dialog will be included in the general framework of the system settings page - * @access public - * @author Christian Reiner - */ - -OCP\Util::addStyle ( '3rdparty', 'chosen/chosen' ); -OCP\Util::addStyle ( 'shorty', 'shorty' ); -OCP\Util::addStyle ( 'shorty', 'settings' ); - -OCP\Util::addScript ( '3rdparty', 'chosen/chosen.jquery.min' ); -OCP\Util::addScript ( 'shorty', 'shorty' ); -OCP\Util::addScript ( 'shorty', 'settings' ); -if ( OC_Log::DEBUG==OC_Config::getValue( "loglevel", OC_Log::WARN ) ) - OCP\Util::addScript ( 'shorty', 'debug' ); - - -// fetch template -$tmpl = new OCP\Template ( 'shorty', 'tmpl_settings' ); -// inflate template -$tmpl->assign ( 'backend-static-base', OCP\Config::getAppValue('shorty','backend-static-base','') ); -// render template -return $tmpl->fetchPage ( ); -?> diff --git a/apps/shorty/templates/tmpl_dlg_qrcode.php b/apps/shorty/templates/tmpl_dlg_qrcode.php deleted file mode 100644 index 15b0eb2c36..0000000000 --- a/apps/shorty/templates/tmpl_dlg_qrcode.php +++ /dev/null @@ -1,52 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_dlg_qrcode.php - * Dialog popup to visualize and offer an url as a QRCode (2D barcode) - * @access public - * @author Christian Reiner - */ -?> - -<!-- additional (hidden) popup dialogs for specific usage actions --> -<fieldset id="dialog-qrcode" style="display:none;" class="" style="align:center;"> - <input id="qrcode-url" type="hidden" value="<?php echo $_['qrcode-url']; ?>"> - <span id='qrcode-img'> - <?php echo $l->t("Click for qrcode url").":"; ?> - <br> - <img width="100%" class="shorty-status" border="1" alt="<?php echo $l->t("QRCode"); ?>" - src="<?php echo OCP\Util::imagePath('shorty','loading-disk.gif'); ?>" > - </span> - <span id='qrcode-val' style="display:none;"> - <?php echo $l->t("Click for qrcode image").":"; ?> - <br> - <span class="shorty-framed"><a title="<?php echo $l->t("QRCode url").":"; ?>"></a></span> - </span> -</fieldset> -<!-- end of qrcode dialog --> diff --git a/apps/shorty/templates/tmpl_dlg_verify.php b/apps/shorty/templates/tmpl_dlg_verify.php deleted file mode 100644 index 14b10d8417..0000000000 --- a/apps/shorty/templates/tmpl_dlg_verify.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_dlg_verify.php - * Dialog popup to validate a configured static backend base - * @access public - * @author Christian Reiner - */ -?> - -<!-- a (usually hidden) dialog used for verification of the correct setup of the 'static' backend --> -<div id="dialog-verification" style="display:none;" title="<?php echo $l->t("'Static' backend: base url verification"); ?>"> - <!-- verification-in-progress --> - <div id="hourglass"> - <img src="<?php echo OCP\Util::imagePath('shorty', 'loading-disk.gif'); ?>"> - </div> - <!-- success --> - <div id="success" style="display:none;"> - <fieldset> - <legend> - <img class="shorty-status" src="<?php echo OCP\Util::imagePath('shorty','status/good.png'); ?>" alt="<?php $l->t('Success') ?>" title="<?php $l->t('Verification successful') ?>"> - <span id="title" class="title"><strong>Verification successful !</strong></span> - </legend> - <?php echo $l->t("<p>Great, your setup appears to be working fine ! </p>". - "<p>Requests to the configured base url '%s' are mapped to this ownClouds shorty module at '%1\$s'</p>". - "<p>Usage of that static backend is fine and safe as long as this setup is not altered.</p>", - array('<a id="verification-target" style="font-family:Monospace;"></a>',OCP\Util::linkToAbsolute('shorty','index.php')) );?> - </fieldset> - </div> - <!-- failure --> - <div id="failure" style="display:none;"> - <fieldset> - <legend> - <img class="shorty-status" src="<?php echo OCP\Util::imagePath('shorty','status/bad.png'); ?>" alt="<?php $l->t('Success') ?>" title="<?php $l->t('Verification successful') ?>"> - <span id="title" class="title"><strong>Verification failed !</strong></span> - </legend> - <?php echo $l->t("Sorry, but your setup appears not be be working correctly yet.<p>". - "Please check your setup and make sure that the configured base url '%1\$s' is indeed correct ". - "and that all requests to it are somehow mapped to ownClouds shorty module at '%2\$s'.", - array('<a id="verification-target" style="font-family:Monospace;"></a>',OCP\Util::linkToAbsolute('shorty','index.php')) );?> - </fieldset> - </div> -</div> -<!-- end of verification dialog --> diff --git a/apps/shorty/templates/tmpl_http_status.php b/apps/shorty/templates/tmpl_http_status.php deleted file mode 100644 index a43b4e3c32..0000000000 --- a/apps/shorty/templates/tmpl_http_status.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_http_status.php - * Displays a human readable version of a classical http status error - * @access public - * @author Christian Reiner - */ -?> - -<ul> - <li class='error'> - <?php echo $_['explanation']; ?> - </li> -</ul> diff --git a/apps/shorty/templates/tmpl_index.php b/apps/shorty/templates/tmpl_index.php deleted file mode 100644 index fc4c4f9161..0000000000 --- a/apps/shorty/templates/tmpl_index.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_index.php - * The general html environment where specific templates are bedded into. - * @access public - * @author Christian Reiner - */ -?> - -<!-- central notification area --> -<div id='notification'></div> - -<!-- top control bar --> -<div id="controls" class="controls shorty-controls" data-referrer="<?php if (array_key_exists('shorty-referrer',$_)) echo $_['shorty-referrer']; ?>"> - <!-- button to add a new entry to list --> - <input type="button" id="add" value="<?php echo OC_Shorty_L10n::t('New Shorty'); ?>"/> - <!-- display label: number of entries in list --> - <span> - <a class="shorty-prompt"><?php echo OC_Shorty_L10n::t('Number of entries') ?>:</a> - <a id="sum_shortys" class="shorty-value"> - <img src="<?php echo OCP\Util::imagePath('core', 'loading.gif'); ?>" /></a> - </span> - <!-- display label: total of clicks in list --> - <span> - <a class="shorty-prompt"><?php echo OC_Shorty_L10n::t('Total of clicks') ?>:</a> - <a id="sum_clicks" class="shorty-value"> - <img src="<?php echo OCP\Util::imagePath('core', 'loading.gif'); ?>" /></a> - </span> - <!-- the dialogs, hidden by default --> -<?php require_once('tmpl_url_add.php'); ?> -<?php require_once('tmpl_url_edit.php'); ?> -<?php require_once('tmpl_url_show.php'); ?> -<?php require_once('tmpl_url_share.php'); ?> -</div> - -<!-- the "desktop where the action takes place --> -<div id="desktop" class="right-content shorty-desktop"> -<?php require_once('tmpl_url_list.php'); ?> -</div> diff --git a/apps/shorty/templates/tmpl_preferences.php b/apps/shorty/templates/tmpl_preferences.php deleted file mode 100644 index 61294c1914..0000000000 --- a/apps/shorty/templates/tmpl_preferences.php +++ /dev/null @@ -1,257 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_preferences.php - * Dialog to change user preferences, to be included in the clouds preferences page. - * @access public - * @author Christian Reiner - */ -?> - -<form id="shorty"> - <fieldset class="personalblock"> - <div id="title" class="title"> - <img class="" src="<?php echo OCP\Util::imagePath("shorty","shorty.png"); ?> "> - <strong>Shorty</strong> - </div> - <div id="settings"> - <!-- shortlet --> - <label for="shortlet" class="aspect"><?php echo $l->t("Shortlet").":";?></label> - <span id="shortlet"> - <a class="shortlet" - href="javascript:(function(){url=encodeURIComponent(location.href);window.open('<?php echo OCP\Util::linkToAbsolute('shorty', 'index.php'); ?>&url='+url, 'owncloud-shorty')%20})()"> - <?php echo $l->t("Add page as 'Shorty' to ownCloud"); ?> - </a> - </span> - <p> - <span class="explain"><em><?php echo $l->t("Drag this to your browser bookmarks."); - echo $l->t("Click it, for whatever site you want to create a Shorty."); ?></em></span> - </p> - <p> - <!-- backend selection --> - <label for="backend-type" class="aspect"><?php echo $l->t("Backend").":";?></label> - <!-- list of available backend types --> - <span style="margin-right:1em;"> - <select id="backend-type" name="backend-type" style="width:11em;" class="chosen" - placeholder="<?php echo $l->t("Choose service…"); ?>" > - <?php - foreach ( $_['backend-types'] as $value=>$display ) - echo sprintf ( " <option value=\"%s\" %s>%s</option>\n", - $value, - ($value==$_['backend-type']?'selected':''), - $l->t($display) ); - ?> - </select> - </span> - <!-- some additional fields: input, explanation and example --> - <!-- depending on the chosen backend-type above only one of the following span tags will be displayed --> - <span id="backend-none" class="backend-supplement" style="display:none;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://%s%s<em><shorty id></em>',$_SERVER['SERVER_NAME'],OCP\Util::linkTo('shorty','',false)) ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo sprintf('%s<br />%s<br />%s', - $l->t("No backend is used, direct links pointing to your ownCloud are generated."), - $l->t("Such links are most likely longer than those generated when using a backend."), - $l->t("However this option does not rely on any third party service and keeps your shortys under your control.") ); ?> - </span> - </span> - <!-- backend -static- --> - <span id="backend-static" class="backend-supplement" style="display:none;"> - <label for="backend-static-base" class="aspect"><?php echo $l->t("Base url").':';?></label> - <input id="backend-static-base" type="text" name="backend-static-base" - readonly disabled value="<?php echo $_['backend-static-base']; ?>" - placeholder="<?php echo $l->t("Specify a backend base url…"); ?>" style="width:25em;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <a id="example" class="example" title="<?php echo $l->t("Verification by click");?>"> - <?php echo sprintf('http://%s/<em><service></em>/<em><shorty id></em>',$_SERVER['SERVER_NAME']) ?> - </a> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo sprintf("%s<br />\n%s<br />\n%s<br />\n%s", - $l->t("A static, rule-based backend is used, shorty links are generated relative to a given base url."), - $l->t("Since this setup depends on server based configuration rules the base url can only be specified in the 'Admin' section of the configuration."), - $l->t("Have a try with the example link provided, click it, it should result in a confirmation that your setup is working."), - $l->t("Only use this backend, if you can provide a short base url that is mapped the described way. Your shorties won't work otherwise.") ); ?> - </span> - </span> - <!-- backend bit.ly --> - <span id="backend-bitly" class="backend-supplement" style="display:none;"> - <label for="backend-bitly-user" class="aspect"><?php echo $l->t("bit.ly user").':';?></label> - <input id="backend-bitly-user" type="text" name="backend-bitly-user" value="<?php echo $_['backend-bitly-user']; ?>" - maxlength="256" placeholder="<?php echo $l->t("bit.ly user name");?>" style="width:10em;"> - <label for="backend-bitly-key" class="aspect"><?php echo $l->t("bit.ly key").':';?></label> - <input id="backend-bitly-key" type="text" name="backend-bitly-key" value="<?php echo $_['backend-bitly-key']; ?>" - maxlength="256" placeholder="<?php echo $l->t("bit.ly users key");?>" style="width:18em;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://bitly.com/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo sprintf("%s<br />\n%s<br />\n%s", - $l->t("The external 'bitly.com' service is used to register a short url for each generated shorty."), - $l->t("The service requires you to authenticate yourself by providing a valid bit.ly user name and an '%s'.", - sprintf('<a class="external" href="http://bitly.com/a/your_api_key" target="_blank">%s</a>',$l->t("API access key")) ), - $l->t("This means you have to '%s' at their site first.", - sprintf('<a class="external" href="http://bitly.com/a/sign_up" target="_blank">%s</a>',$l->t("register an account")) ) ); ?> - </span> - </span> - <!-- backend cligs --> - <span id="backend-cligs" class="backend-supplement" style="display:none;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://cli.gs/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo $l->t("The external 'cli.gs' service is used to register a short url for each generated shorty.");?> - </span> - </span> - <!-- backend is.gd --> - <span id="backend-isgd" class="backend-supplement" style="display:none;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://is.gd/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo $l->t("The external 'is.gd' service is used to register a short url for each generated shorty.");?> - </span> - </span> - <!-- backend google --> - <span id="backend-google" class="backend-supplement" style="display:none;"> - <label for="backend-google-key" class="aspect"><?php echo $l->t("API key").':';?></label> - <input id="backend-google-key" type="text" name="backend-google-key" value="<?php echo $_['backend-google-key']; ?>" - maxlength="256" placeholder="<?php echo $l->t("Google API key");?>" style="width:24em;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://goo.gl/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo sprintf("%s<br />\n%s<br />\n%s<br />\n%s", - $l->t("Googles external 'goo.gl service' is used to register a short url for each generated shorty."), - $l->t("You must provide a valid '%s' to use this service.", - sprintf('<a class="external" href="https://code.google.com/apis/console/" target="_blank">%s</a>',$l->t("Google API key")) ), - $l->t("This means you require a 'Google API console account'."), - $l->t("Register a new '%s' at their pages.", array( - sprintf('<a class="external" href="https://code.google.com/apis/console/" target="_blank">%s</a>',$l->t("Google API account")) ) ) );?> - </span> - </span> - <!-- backend tinycc --> - <span id="backend-tinycc" class="backend-supplement" style="display:none;"> - <label for="backend-tinycc-user" class="aspect"><?php echo $l->t("tiny.cc user").':'; ?></label> - <input id="backend-tinycc-user" type="text" name="backend-tinycc-user" value="<?php echo $_['backend-tinycc-user']; ?>" - maxlength="256" placeholder="<?php echo $l->t("tiny.cc user name"); ?>" style="width:10em;"> - <label for="backend-tinycc-key" class="aspect"><?php echo $l->t("tiny.cc key").':'; ?></label> - <input id="backend-tinycc-key" type="text" name="backend-tinycc-key" value="<?php echo $_['backend-tinycc-key']; ?>" - maxlength="256" placeholder="<?php echo $l->t("tiny.cc user key"); ?>" style="width:19em;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <span id="example" class="example"><?php echo sprintf('http://tiny.cc/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo sprintf ( "%s<br />\n%s<br />\n%s", - $l->t("The external 'tiny.cc' service is used to register a short url for each generated shorty."), - $l->t("The service requires you to authenticate yourself by providing a valid tiny.cc user name and an api access key."), - $l->t("This means you have to register an '%s' at their site first.", array ( - sprintf('<a class="external" href="http://tiny.ccc/" target="_blank">%s</a>', $l->t("account") ) ) ) ); ?> - </span> - </span> - <!-- backend tinyURL --> - <span id="backend-tinyurl" class="backend-supplement" style="display:none;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':'; ?></label> - <span id="example" class="example"><?php echo sprintf('http://ti.ny/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo $l->t("The external 'ti.ny' service is used to register a short url for each generated shorty.");?> - </span> - </span> - <!-- backend turl --> - <span id="backend-turl" class="backend-supplement" style="display:none;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':'; ?></label> - <span id="example" class="example"><?php echo sprintf('http://turl.ca/<em><shorty id></em>') ?></span> - </span> - <br/> - <span id="explain" class="explain"> - <?php echo $l->t("The external 'turl' service is used to register a short url for each generated shorty."); ?> - </span> - </span> - </p> - <p> - <!-- sms --> - <label for="sms" class="aspect"><?php echo $l->t("SMS").":";?></label> - <span id="sms" style="margin-right:1em;"> - <select id="sms-control" name="sms-control" style="width:11em;" class="chosen"> - <?php echo sprintf("<option value=\"disabled\" %s>%s</option>\n", - ('enabled'!=$_['sms-control']?'selected':''), - $l->t('disabled') ); ?> - <?php echo sprintf("<option value=\"enabled\" %s>%s</option>\n", - ('enabled'==$_['sms-control']?'selected':''), - $l->t('enabled')); ?> - </select> - <em><?php echo $l->t("Enabling the SMS option will offer sending a Shorty via SMS."); ?></em> - </span> - <p> - <span class="explain"><em><?php echo $l->t("Unfortunately support for 'SMS url handling' is usually only found on mobile devices like smart phones.")."<br>\n"; - echo $l->t("In addition, the implementations found in Android or iOS are minimalistic, buggy and differ from system to system.")."<br>\n"; - echo $l->t("In short: this might not work for you, therefore you can disable it…")."<br>\n";?></em></span> - </p> - </div> - <!-- a (usually hidden) dialog used for verification of the correct setup of the 'static' backend --> - <?php require_once('tmpl_dlg_verify.php'); ?> - </fieldset> -</form> diff --git a/apps/shorty/templates/tmpl_settings.php b/apps/shorty/templates/tmpl_settings.php deleted file mode 100644 index bcbab5ae01..0000000000 --- a/apps/shorty/templates/tmpl_settings.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_settings.php - * Dialog to change plugin settings, to be included in the clouds settings page. - * @access public - * @author Christian Reiner - */ -?> - -<!-- settings of app 'shorty' --> -<form id="shorty"> - <fieldset class="personalblock"> - <legend> - <span id="title" class="title"> - <img class="" src="<?php echo OCP\Util::imagePath("shorty","shorty.png"); ?> "> - <strong>Shorty</strong> - </span> - </legend> - <div id="backend-static" class="backend-supplement"> - <label for="backend-static-base" class="aspect"><?php echo $l->t("Base url").':';?></label> - <input id="backend-static-base" type="text" name="backend-static-base" - value="<?php echo $_['backend-static-base']; ?>" - maxlength="256" placeholder="<?php echo $l->t('Specify a static base url…');?>" style="width:25em;"> - <br/> - <label for="backend-example" class="aspect"> </label> - <span id="backend-example"> - <label for="example" class="aspect"><?php echo $l->t("Example").':';?></label> - <a id="example" class="example" title="<?php echo $l->t("Verification by click");?>"> - <?php echo sprintf('http://%s/<em><service></em>/<em><shorty id></em>',$_SERVER['SERVER_NAME']) ?> - </a> - </span> - <br/> - <span id="explain" class="explain"><?php echo sprintf("%s<br />\n%s<br />\n%s<br />\n%s", - $l->t("Static, rule-based backend, generates shorty links relative to a given base url."), - $l->t("You have to take care that any request to the url configured here is internally mapped to the 'shorty' module."), - $l->t("Have a try with the example link provided, click it, it should result in a confirmation that your setup is working."), - $l->t("Leave empty if you can't provide a short base url that is mapped the described way.") ); ?> - </span> - </div> - - <?php require_once('tmpl_dlg_verify.php'); ?> - </fieldset> -</form> diff --git a/apps/shorty/templates/tmpl_url_add.php b/apps/shorty/templates/tmpl_url_add.php deleted file mode 100644 index abf51bdab7..0000000000 --- a/apps/shorty/templates/tmpl_url_add.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_url_add.php - * A dialog to add a remote target url as a new shorty. - * @access public - * @author Christian Reiner - */ -?> - -<!-- (hidden) dialog to add a new shorty --> -<form id="dialog-add" class="shorty-dialog shorty-standalone"> - <fieldset> - <legend class=""> - <a id="close" class="shorty-close-button" - title="<?php echo OC_Shorty_L10n::t('Close'); ?>"> - <img alt="<?php echo OC_Shorty_L10n::t('Close'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/shade.png'); ?>"> - </a> - <?php echo OC_Shorty_L10n::t('Add a new shorty').':'; ?> - </legend> - <label for="target"><?php echo OC_Shorty_L10n::t('Target url').':'; ?></label> - <input id="target" name="target" type="text" maxlength="4096" data="" class=""/> - <br /> - <label for="meta"> <img id="busy" height="12px" src="<?php echo OCP\Util::imagePath('shorty', 'loading-led.gif'); ?>"></label> - <span id="meta" class="shorty-meta"> - <img id="staticon" class="shorty-icon" src="" width="16" data="<?php echo OCP\Util::imagePath('shorty', 'status/neutral.png'); ?>"> - <img id="schemicon" class="shorty-icon" src="" width="16" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="favicon" class="shorty-icon" src="" width="16" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="mimicon" class="shorty-icon" src="" width="16" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <a id="explanation" maxlength="80" data="" class="shorty-value"></a> - </span> - <br /> - <label for="title"><?php echo OC_Shorty_L10n::t('Shorty title').':'; ?></label> - <input id="title" name="title" type="text" maxlength="80" data="" class="" placeholder=""/> - <br /> - <label for="status"><?php echo OC_Shorty_L10n::t('Status').':'; ?></label> - <select id="status" name="status" data="shared" value="shared" class=""> - <?php - foreach ( OC_Shorty_Type::$STATUS as $status ) - if ( 'deleted'!=$status ) - echo sprintf ( "<option value=\"%s\">%s</option>\n", $status, OC_Shorty_L10n::t($status) ); - ?> - </select> - <span style="display:inline-block;"> - <label for="until"><?php echo OC_Shorty_L10n::t('Expiration').':'; ?></label> - <input id="until" name="until" type="text" maxlength="10" value="" - data="" class="" style="width:8em;" - placeholder="-<?php echo OC_Shorty_L10n::t('never'); ?>-" - icon="<?php echo OCP\Util::imagePath('shorty', 'calendar.png'); ?>"/> - </span> - <br /> - <label for="notes"><?php echo OC_Shorty_L10n::t('Notes').':'; ?></label> - <textarea id="notes" name="notes" maxlength="4096" data="" class="" - placeholder="<?php echo OC_Shorty_L10n::t('Anything that appears helpful …'); ?>"></textarea> - <br /> - <label for="confirm"></label> - <button id="confirm" class="shorty-button-submit"><?php echo OC_Shorty_L10n::t('Add as new'); ?></button> - </fieldset> -</form> diff --git a/apps/shorty/templates/tmpl_url_edit.php b/apps/shorty/templates/tmpl_url_edit.php deleted file mode 100644 index 395b75ecab..0000000000 --- a/apps/shorty/templates/tmpl_url_edit.php +++ /dev/null @@ -1,100 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_url_edit.php - * A dialog to modify some aspects of a selected shorty. - * @access public - * @author Christian Reiner - */ -?> - -<!-- (hidden) dialog to modify a stored shorty --> -<form id="dialog-edit" class="shorty-dialog shorty-standalone"> - <fieldset> - <legend class=""> - <a id="close" class="shorty-close-button" - title="<?php echo OC_Shorty_L10n::t('Close'); ?>"> - <img alt="<?php echo OC_Shorty_L10n::t('Close'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/shade.png'); ?>"> - </a> - <?php echo OC_Shorty_L10n::t('Modify shorty').':'; ?> - </legend> - <input id="id" name="id" type="hidden" readonly data="" class="" readonly disabled /> - <label for="source"><?php echo OC_Shorty_L10n::t('Source url').':'; ?></label> - <input id="source" name="source" type="text" data="" class="" readonly disabled /> - <br /> - <label for="target"><?php echo OC_Shorty_L10n::t('Target url').':'; ?></label> - <input id="target" name="target" type="text" data="" class="" readonly /> - <br /> - <label for="meta"> </label> - <span id="meta"> - <img id="staticon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'status/neutral.png'); ?>"> - <img id="schemicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="favicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="mimicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <a id="explanation" maxlength="80" data="" class="shorty-value"></a> - </span> - <br /> - <label for="title"><?php echo OC_Shorty_L10n::t('Shorty title').':'; ?></label> - <input id="title" name="title" type="text" maxlength="80" data="" class="" /> - <br /> - <label for="status"><?php echo OC_Shorty_L10n::t('Status').':'; ?></label> - <select id="status" name="status" data="shared" value="shared" style="width:8em;" class=""> - <?php - foreach ( OC_Shorty_Type::$STATUS as $status ) - if ( 'deleted'!=$status ) - echo sprintf ( "<option value=\"%s\">%s</option>\n", $status, OC_Shorty_L10n::t($status) ); - ?> - </select> - <span style="display:inline;"> - <label for="until"><?php echo OC_Shorty_L10n::t('Expiration').':'; ?></label> - <input id="until" name="until" type="text" value="" - maxlength="10" data="" class="" style="width:8em;" - placeholder="-<?php echo OC_Shorty_L10n::t('never'); ?>-" - icon="<?php echo OCP\Util::imagePath('shorty', 'calendar.png'); ?>" /> - </span> - <br /> - <label for="notes"><?php echo OC_Shorty_L10n::t('Notes').':'; ?></label> - <textarea id="notes" name="notes" maxlength="4096" data="" class="" - placeholder="<?php echo OC_Shorty_L10n::t('Anything that appears helpful …'); ?>"> - </textarea> - <br /> - <span class="label-line"> - <label for="clicks"><?php echo OC_Shorty_L10n::t('Clicks').':'; ?></label> - <input id="clicks" name="clicks" data="" type="textarea" class="" style="width:1em;" readonly disabled /> - <label for="created"><?php echo OC_Shorty_L10n::t('Creation').':'; ?></label> - <input id="created" name="created" type="text" data="" class="" style="width:7em;" readonly disabled /> - <label for="accessed"><?php echo OC_Shorty_L10n::t('Access').':'; ?></label> - <input id="accessed" name="accessed" type="text" data="" class="" style="width:10em;" readonly disabled /> - </span> - <br /> - <label for="confirm"></label> - <button id="confirm" class="shorty-button-submit"><?php echo OC_Shorty_L10n::t('Save'); ?></button> - </fieldset> -</form> diff --git a/apps/shorty/templates/tmpl_url_list.php b/apps/shorty/templates/tmpl_url_list.php deleted file mode 100644 index 7a93eab9d8..0000000000 --- a/apps/shorty/templates/tmpl_url_list.php +++ /dev/null @@ -1,167 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_url_list.php - * A table to visualize the list of existing shortys. - * @access public - * @author Christian Reiner - */ -?> - -<div id="hourglass" class="shorty-hourglass" style="left:10em;top:10em;"><img src="<?php echo OCP\Util::imagePath('shorty', 'loading-disk.gif'); ?>"></div> -<div id="vacuum" class="shorty-vacuum"><span class="shorty-label"><?php echo OC_Shorty_L10n::t('List currently empty.') ?></span></div> - -<!-- the list of urls --> -<table id="list" class="shorty-list" style="display:none;"> - <thead> - <tr id="titlebar"> - <!-- a button to open/close the toolbar below --> - <th id="favicon"><span><img id="tools" alt="toolbar" title="toggle toolbar" - src="<?php echo OCP\Util::imagePath('shorty','actions/plus.png'); ?>" - data-plus="<?php echo OCP\Util::imagePath('shorty','actions/plus.png'); ?>" - data-minus="<?php echo OCP\Util::imagePath('shorty','actions/minus.png'); ?>"></span></th> - <th id="title" ><span><?php echo OC_Shorty_L10n::t('Title') ?></span></th> - <th id="target" ><span><?php echo OC_Shorty_L10n::t('Target') ?></span></th> - <th id="clicks" ><span><?php echo OC_Shorty_L10n::t('Clicks') ?></span></th> - <th id="until" ><span><?php echo OC_Shorty_L10n::t('Expiration') ?></span></th> - <th id="status" ><span><?php echo OC_Shorty_L10n::t('Status') ?></span></th> - <th id="action" ><span> </span></th> - </tr> - <!-- toolbar opened/closed by the button above --> - <tr id="toolbar"> - <th id="favicon"> - <div style="display:none;"> - <a id="reload"><img alt="<?php echo $l->t('reload'); ?>" title="<?php echo $l->t('Reload list'); ?>" src="<?php echo OCP\Util::imagePath('shorty','actions/reload.png'); ?>"></a> - </div> - </th> - <th id="title"> - <div style="display:none;"> - <img id="sort-up" class="shorty-sorter" data-sort-code="ta" data-sort-type="string" data-sort-direction='asc' - alt="<?php echo $l->t('up'); ?>" title="<?php echo $l->t('Sort ascending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/up.png'); ?>"> - <img id="sort-down" class="shorty-sorter" data-sort-code="td" data-sort-type="string" data-sort-direction='desc' - alt="<?php echo $l->t('down'); ?>" title="<?php echo $l->t('Sort descending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/down.png'); ?>"> - <input id='filter' type="text" value=""> - </div> - </th> - <th id="target"> - <div style="display:none;"> - <img id="sort-up" class="shorty-sorter" data-sort-code="ua" data-sort-type="string" data-sort-direction='asc' - alt="<?php echo $l->t('up'); ?>" title="<?php echo $l->t('Sort ascending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/up.png'); ?>"> - <img id="sort-down" class="shorty-sorter" data-sort-code="ud" data-sort-type="string" data-sort-direction='desc' - alt="<?php echo $l->t('down'); ?>" title="<?php echo $l->t('Sort descending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/down.png'); ?>"> - <input id='filter' type="text" value=""> - </div> - </th> - <th id="clicks"> - <div style="display:none;"> - <img id="sort-up" class="shorty-sorter" data-sort-code="ha" data-sort-type="int" data-sort-direction='asc' - alt="<?php echo $l->t('up'); ?>" title="<?php echo $l->t('Sort ascending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/up.png'); ?>"> - <img id="sort-down" class="shorty-sorter" data-sort-code="hd" data-sort-type="int" data-sort-direction='desc' - alt="<?php echo $l->t('down'); ?>" title="<?php echo $l->t('Sort descending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/down.png'); ?>"> - </div> - </th> - <th id="until"> - <div style="display:none;"> - <img id="sort-up" class="shorty-sorter" data-sort-code="da" data-sort-type="date" data-sort-direction='asc' - alt="<?php echo $l->t('up'); ?>" title="<?php echo $l->t('Sort ascending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/up.png'); ?>"> - <img id="sort-down" class="shorty-sorter" data-sort-code="dd" data-sort-type="date" data-sort-direction='desc' - alt="<?php echo $l->t('down'); ?>" title="<?php echo $l->t('Sort descending'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/down.png'); ?>"> - </div> - </th> - <!-- status filter, colspan 2 to prevent width enhancement of column --> - <th id="status" colspan=2> - <div style="display:none;"> - <span id="horst" class="shorty-select"> - <select id='filter' value="" data-placeholder=" "> - <?php foreach($_['shorty-status'] as $status=>$label) - echo sprintf("<option value=\"%s\">%s</option>\n",($status?$label:''),$label); - ?> - </select> - </span> - </div> - </th> - </tr> - <!-- the 'dummy' row, a blueprint --> - <tr id="" - data-id="" - data-status="" - data-source="" - data-relay="" - data-title="" - data-favicon="" - data-target="" - data-clicks="" - data-until="" - data-created="" - data-accessed="" - data-notes=""> - <td id="favicon"></td> - <td id="title" ></td> - <td id="target" ></td> - <td id="clicks" ></td> - <td id="until" ></td> - <td id="status" ></td> - <td id="actions"> - <span class="shorty-actions"> - <a id="show" title="<?php echo $l->t('show'); ?>" class=""> - <img class="shorty-icon" alt="<?php echo $l->t('show'); ?>" title="<?php echo $l->t('Show details'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/info.png'); ?>" /> - </a> - <a id="edit" title="<?php echo $l->t('edit'); ?>" class=""> - <img class="shorty-icon" alt="<?php echo $l->t('modify'); ?>" title="<?php echo $l->t('Modify shorty'); ?>" - src="<?php echo OCP\Util::imagePath('core','actions/rename.png'); ?>" /> - </a> - <a id="del" title="<?php echo $l->t('delete'); ?>" class=""> - <img class="shorty-icon" alt="<?php echo $l->t('delete'); ?>" title="<?php echo $l->t('Delete shorty'); ?>" - src="<?php echo OCP\Util::imagePath('core','actions/delete.png'); ?>" /> - </a> - <a id="share" title="<?php echo $l->t('share'); ?>" class=""> - <img class="shorty-icon" alt="<?php echo $l->t('share'); ?>" title="<?php echo $l->t('Test and use links'); ?>" - src="<?php echo OCP\Util::imagePath('core','actions/share.png'); ?>" /> - </a> - <a id="open" title="<?php echo $l->t('open'); ?>" class=""> - <img class="shorty-icon" alt="<?php echo $l->t('open'); ?>" title="<?php echo $l->t('Open target'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/open.png'); ?>" /> - </a> - </span> - </td> - </tr> - </thead> - <!-- the standard body for non-empty lists --> - <tbody> - </tbody> -</table> diff --git a/apps/shorty/templates/tmpl_url_share.php b/apps/shorty/templates/tmpl_url_share.php deleted file mode 100644 index b42396d6a0..0000000000 --- a/apps/shorty/templates/tmpl_url_share.php +++ /dev/null @@ -1,89 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_url_share.php - * A dialog offering control over an entries state and offers the source url - * @access public - * @author Christian Reiner - */ -?> - -<!-- (hidden) dialog to share a shorty from the list --> -<form id="dialog-share" class="shorty-dialog shorty-embedded"> - <fieldset> - <legend class=""> - <a id="close" class="shorty-close-button" - title="<?php echo OC_Shorty_L10n::t('Close'); ?>"> - <img alt="<?php echo OC_Shorty_L10n::t('Close'); ?>" - src="<?php echo OCP\Util::imagePath('apps/shorty','actions/shade.png'); ?>"> - </a> - <?php echo OC_Shorty_L10n::t('Test and use').':'; ?> - </legend> - <input id="id" name="id" type="hidden" readonly data="" class="" readonly disabled /> - <label for="status"><?php echo OC_Shorty_L10n::t('Status').':'; ?></label> - <select id="status" name="status" data="" class="" value=""> - <?php - foreach ( OC_Shorty_Type::$STATUS as $status ) - if ( 'deleted'!=$status ) - echo sprintf ( "<option value=\"%s\">%s</option>\n", $status, OC_Shorty_L10n::t($status) ); - ?> - </select> - <br /> - <label for="source"><?php echo OC_Shorty_L10n::t('Source url').':'; ?></label> - <a id="source" class="shorty-clickable" target="_blank" - title="<?php echo OC_Shorty_L10n::t('Open source url'); ?>" - href=""></a> - <br /> - <label for="relay"><?php echo OC_Shorty_L10n::t('Relay url').':'; ?></label> - <a id="relay" class="shorty-clickable" target="_blank" - title="<?php echo OC_Shorty_L10n::t('Open relay url'); ?>" - href=""></a> - <br /> - <label for="target"><?php echo OC_Shorty_L10n::t('Target url').':'; ?></label> - <a id="target" class="shorty-clickable" target="_blank" - title="<?php echo OC_Shorty_L10n::t('Open target url'); ?>" - href=""></a> - <br /> - <img id="usage-email" name="usage-email" class="shorty-usage" alt="email" - src="<?php echo OCP\Util::imagePath('apps/shorty','usage/64/email.png'); ?>" - title="<?php echo OC_Shorty_L10n::t("Send by email"); ?>" /> - <img id="usage-sms" type="image" name="usage-sms" alt="sms" - class="shorty-usage <?php echo $_['sms-control']; ?>" - src="<?php echo OCP\Util::imagePath('apps/shorty','usage/64/sms.png'); ?>" - title="<?php echo OC_Shorty_L10n::t("Send by SMS"); ?>" /> - <img id="usage-qrcode" type="image" name="usage-qrcode" class="shorty-usage" alt="qrcode" - src="<?php echo OCP\Util::imagePath('apps/shorty','usage/64/qrcode.png'); ?>" - title="<?php echo OC_Shorty_L10n::t("Show as QRCode"); ?>" /> - <img id="usage-clipboard" type="image" name="usage-clipboard" class="shorty-usage" alt="clipbaord" - src="<?php echo OCP\Util::imagePath('apps/shorty','usage/64/clipboard.png'); ?>" - title="<?php echo OC_Shorty_L10n::t("Copy to clipboard"); ?>" /> - </fieldset> -</form> - -<?php require_once('tmpl_dlg_qrcode.php'); ?> diff --git a/apps/shorty/templates/tmpl_url_show.php b/apps/shorty/templates/tmpl_url_show.php deleted file mode 100644 index 462d8e8b9c..0000000000 --- a/apps/shorty/templates/tmpl_url_show.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php -/** -* @package shorty an ownCloud url shortener plugin -* @category internet -* @author Christian Reiner -* @copyright 2011-2012 Christian Reiner <foss@christian-reiner.info> -* @license GNU Affero General Public license (AGPL) -* @link information -* @link repository https://svn.christian-reiner.info/svn/app/oc/shorty -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the license, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. -* If not, see <http://www.gnu.org/licenses/>. -* -*/ -?> - -<?php -/** - * @file templates/tmpl_url_show.php - * A read-only dialog visualizing all aspects of a selected shorty. - * @access public - * @author Christian Reiner - */ -?> - -<!-- (hidden) dialog to show a shorty from the list --> -<form id="dialog-show" class="shorty-dialog shorty-standalone"> - <fieldset> - <legend class=""> - <a id="close" class="shorty-close-button" - title="<?php echo OC_Shorty_L10n::t('Close'); ?>"> - <img alt="<?php echo OC_Shorty_L10n::t('Close'); ?>" - src="<?php echo OCP\Util::imagePath('shorty','actions/shade.png'); ?>"> - </a> - <?php echo OC_Shorty_L10n::t('Show details').':'; ?> - </legend> - <label for="source"><?php echo OC_Shorty_L10n::t('Source url').':'; ?></label> - <input id="source" name="source" type="text" data="" class="" readonly disabled /> - <br /> - <label for="target"><?php echo OC_Shorty_L10n::t('Target url').':'; ?></label> - <input id="target" name="target" data="" class="" readonly disabled /> - <br /> - <label for="meta"> </label> - <span id="meta"> - <img id="staticon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'status/neutral.png'); ?>"> - <img id="schemicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="favicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <img id="mimicon" class="shorty-icon" src="" data="<?php echo OCP\Util::imagePath('shorty', 'blank.png'); ?>"> - <a id="explanation" maxlength="80" data="" class="shorty-value"></a> - </span> - <br /> - <label for="title"><?php echo OC_Shorty_L10n::t('Shorty title').':'; ?></label> - <input id="title" name="title" type="text" data="" class="" readonly disabled /> - <br /> - <label for="status"><?php echo OC_Shorty_L10n::t('Status').':'; ?></label> - <input id="status" name="status" type="text" data="" class="" style="width:8em;" readonly disabled /> - <span class="label-line"> - <label for="until"><?php echo OC_Shorty_L10n::t('Expiration').':'; ?></label> - <input id="until" name="until" type="text" data="" class="" style="width:12em;" readonly disabled /> - </span> - <br /> - <label for="notes"><?php echo OC_Shorty_L10n::t('Notes').':'; ?></label> - <input id="notes" name="notes" data="" class="" readonly disabled /> - <br /> - <span class="label-line"> - <label for="clicks"><?php echo OC_Shorty_L10n::t('Clicks').':'; ?></label> - <input id="clicks" name="clicks" data="" type="textarea" class="" style="width:1em;" readonly disabled /> - <label for="created"><?php echo OC_Shorty_L10n::t('Creation').':'; ?></label> - <input id="created" name="created" type="text" data="" class="" style="width:7em;" readonly disabled /> - <label for="accessed"><?php echo OC_Shorty_L10n::t('Access').':'; ?></label> - <input id="accessed" name="accessed" type="text" data="" class="" style="width:10em;" readonly disabled /> - </span> - </fieldset> -</form> diff --git a/apps/storage_charts/ajax/config.php b/apps/storage_charts/ajax/config.php deleted file mode 100644 index 22fa038429..0000000000 --- a/apps/storage_charts/ajax/config.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('storage_charts'); - -if(in_array($_POST['k'], Array('hu_size','sc_sort','hu_size_hus'))){ - switch($_POST['o']){ - case 'set': - $i = NULL; - if(is_array($_POST['i'])){ - $i = serialize($_POST['i']); - - }elseif(is_numeric($_POST['i'])){ - $i = $_POST['i']; - } - OC_DLStCharts::setUConfValue($_POST['k'], $i); - break; - case 'get': - $v = OC_DLStCharts::getUConfValue($_POST['k']); - OCP\JSON::encodedPrint(Array('r' => $v['uc_val'])); - break; - } -} diff --git a/apps/storage_charts/ajax/data.php b/apps/storage_charts/ajax/data.php deleted file mode 100644 index a9a36d3c64..0000000000 --- a/apps/storage_charts/ajax/data.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('storage_charts'); - -$l = new OC_L10N('storage_charts'); - -// Update and save the new configuration -if(is_numeric($_POST['s']) && in_array($_POST['k'], Array('hu_size','hu_size_hus'))){ - OC_DLStCharts::setUConfValue($_POST['k'], $_POST['s']); - if(strcmp($_POST['k'],'hu_size') == 0){ - OCP\JSON::encodedPrint(Array('r' => OC_DLStChartsLoader::loadChart('clines_usse', $l))); - }else{ - OCP\JSON::encodedPrint(Array('r' => OC_DLStChartsLoader::loadChart('chisto_us', $l))); - } -} diff --git a/apps/storage_charts/appinfo/app.php b/apps/storage_charts/appinfo/app.php deleted file mode 100644 index 3efec67ea8..0000000000 --- a/apps/storage_charts/appinfo/app.php +++ /dev/null @@ -1,51 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\App::checkAppEnabled('storage_charts'); - -OC::$CLASSPATH['OC_DLStCharts'] = "apps/storage_charts/lib/db.class.php"; -OC::$CLASSPATH['OC_DLStChartsLoader'] = "apps/storage_charts/lib/loader.class.php"; - -OCP\App::register(Array( - 'order' => 60, - 'id' => 'storage_charts', - 'name' => 'Storage Charts' -)); - -OCP\App::addNavigationEntry(Array( - 'id' => 'storage_charts', - 'order' => 60, - 'href' => OCP\Util::linkTo('storage_charts', 'charts.php'), - 'icon' => OCP\Util::imagePath('storage_charts', 'chart.png'), - 'name' => 'DL Charts' -)); - -OCP\App::registerPersonal('storage_charts','settings'); - -$data_dir = OCP\Config::getSystemValue('datadirectory', ''); -if(OCP\User::getUser() && strlen($data_dir) != 0){ - $fs = OCP\Files::getStorage('files'); - $used = OC_DLStCharts::getTotalDataSize(OC::$CONFIG_DATADIRECTORY); - $total = OC_DLStCharts::getTotalDataSize($data_dir) + $fs->free_space(); - OC_DLStCharts::update($used, $total); -} diff --git a/apps/storage_charts/appinfo/app_admin.php b/apps/storage_charts/appinfo/app_admin.php deleted file mode 100644 index 9181d2f54b..0000000000 --- a/apps/storage_charts/appinfo/app_admin.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\App::checkAppEnabled('storage_charts'); - -$l = OC_L10N::get('storage_charts'); - -OC::$CLASSPATH['OC_DLStCharts'] = "apps/storage_charts/lib/db.class.php"; -OC::$CLASSPATH['OC_DLStChartsLoader'] = "apps/storage_charts/lib/loader.class.php"; - -if(OC_Group::inGroup(OCP\User::getUser(), 'admin')){ - OCP\App::register(Array( - 'order' => 60, - 'id' => 'storage_charts', - 'name' => 'Storage Charts' - )); - - OCP\App::addNavigationEntry(Array( - 'id' => 'storage_charts', - 'order' => 60, - 'href' => OCP\Util::linkTo('storage_charts', 'charts.php'), - 'icon' => OCP\Util::imagePath('storage_charts', 'chart.png'), - 'name' => 'DL Charts' - )); - - OCP\App::registerPersonal('storage_charts','settings'); -}elseif(OCP\User::isLoggedIn() && $_GET['app'] == 'storage_charts'){ - die($l->t('Permission denied.')); -} - -// Get storage value for logged in user -$data_dir = OCP\Config::getSystemValue('datadirectory', ''); -if(OCP\User::getUser() && strlen($data_dir) != 0){ - $fs = OCP\Files::getStorage('files'); - $used = OC_DLStCharts::getTotalDataSize(OC::$CONFIG_DATADIRECTORY); - $total = OC_DLStCharts::getTotalDataSize($data_dir) + $fs->free_space(); - OC_DLStCharts::update($used, $total); -} \ No newline at end of file diff --git a/apps/storage_charts/appinfo/database.xml b/apps/storage_charts/appinfo/database.xml deleted file mode 100644 index cac8136d2e..0000000000 --- a/apps/storage_charts/appinfo/database.xml +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="ISO-8859-1" ?> -<database> - <name>*dbname*</name> - <create>true</create> - <overwrite>false</overwrite> - <charset>utf8</charset> - <table> - <name>*dbprefix*dlstcharts</name> - <declaration> - <field> - <name>stc_id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - <field> - <name>oc_uid</name> - <type>text</type> - <notnull>true</notnull> - <length>64</length> - </field> - <field> - <name>stc_month</name> - <type>integer</type> - <notnull>true</notnull> - <length>6</length> - </field> - <field> - <name>stc_dayts</name> - <type>integer</type> - <notnull>true</notnull> - <length>11</length> - </field> - <field> - <name>stc_used</name> - <type>integer</type> - <notnull>true</notnull> - <length>30</length> - </field> - <field> - <name>stc_total</name> - <type>integer</type> - <notnull>true</notnull> - <length>30</length> - </field> - <index> - <name>stc_pk</name> - <primary>true</primary> - <field> - <name>stc_id</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - </table> - <table> - <name>*dbprefix*dlstcharts_uconf</name> - <declaration> - <field> - <name>uc_id</name> - <type>integer</type> - <default>0</default> - <notnull>true</notnull> - <autoincrement>1</autoincrement> - <unsigned>true</unsigned> - <length>4</length> - </field> - <field> - <name>oc_uid</name> - <type>text</type> - <notnull>true</notnull> - <length>64</length> - </field> - <field> - <name>uc_key</name> - <type>text</type> - <notnull>true</notnull> - <length>64</length> - </field> - <field> - <name>uc_val</name> - <type>text</type> - <notnull>true</notnull> - <length>255</length> - </field> - <index> - <name>uc_pk</name> - <primary>true</primary> - <field> - <name>uc_id</name> - <sorting>ascending</sorting> - </field> - </index> - </declaration> - </table> -</database> diff --git a/apps/storage_charts/appinfo/info.xml b/apps/storage_charts/appinfo/info.xml deleted file mode 100644 index 435c5a4093..0000000000 --- a/apps/storage_charts/appinfo/info.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0"?> -<info> - <id>storage_charts</id> - <name>Storage Charts</name> - <description>Display storage charts, using HighCharts non-commercial free library (www.highcharts.com)</description> - <version>2.2</version> - <licence>AGPL</licence> - <author>Xavier Beurois (www.djazz-lab.net)</author> - <require>4</require> - <shipped>true</shipped> -</info> diff --git a/apps/storage_charts/charts.php b/apps/storage_charts/charts.php deleted file mode 100644 index 774f113554..0000000000 --- a/apps/storage_charts/charts.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\User::checkLoggedIn(); -OCP\App::checkAppEnabled('storage_charts'); - -$tmpl = new OCP\Template('storage_charts', 'charts.tpl', 'user'); - -// Get data for all users if admin or just for the current user -$displays = OC_DLStCharts::getUConfValue('c_disp', Array('uc_val' => 'a:3:{s:10:"cpie_rfsus";i:1;s:11:"clines_usse";i:1;s:9:"chisto_us";i:1;}')); -$displays = unserialize($displays['uc_val']); -$tmpl->assign('c_disp', $displays); - -$sc_sort = OC_DLStCharts::getUConfValue('sc_sort', Array('uc_val' => 'a:3:{i:0;s:10:"cpie_rfsus";i:1;s:11:"clines_usse";i:2;s:9:"chisto_us";}')); -$tmpl->assign('sc_sort', unserialize($sc_sort['uc_val'])); - -if($displays['clines_usse']){ - $hu_size = OC_DLStCharts::getUConfValue('hu_size', Array('uc_val' => 3)); - $tmpl->assign('hu_size', $hu_size['uc_val']); -} -if($displays['chisto_us']){ - $hu_size_hus = OC_DLStCharts::getUConfValue('hu_size_hus', Array('uc_val' => 3)); - $tmpl->assign('hu_size_hus', $hu_size_hus['uc_val']); -} - -$tmpl->printPage(); diff --git a/apps/storage_charts/css/styles.css b/apps/storage_charts/css/styles.css deleted file mode 100644 index e5fb7a3dad..0000000000 --- a/apps/storage_charts/css/styles.css +++ /dev/null @@ -1,32 +0,0 @@ -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -#storage-charts div.personalblock.topblock span{float:right;color:#BBB;font-style:italic;} - -#stc_sortable div.personalblock.bottomblock, #storage-charts div.personalblock.bottomblock{margin-bottom:1em;} -#stc_sortable div.personalblock.titleblock, #storage-charts div.personalblock.titleblock{font-weight:bold;} -#stc_sortable div.personalblock, #storage-charts div.personalblock{margin:1em 1em 0;padding:0.5em 1em;background: none repeat scroll 0 0 #F8F8F8;border-radius:0.5em 0.5em 0.5em 0.5em;color:#555555;text-shadow:0 1px 0 #FFFFFF;border:1px solid #DDDDDD;box-shadow:0 1px 1px #FFFFFF,0 1px 1px #FFFFFF inset;} - -#stc_frame{margin:1em 1em 0;} -#stc_frame #stc_sortable div.personalblock{margin:0;margin-bottom:1em;} -#stc_frame #stc_sortable div.personalblock h3{line-height:2.6;} -#stc_frame #stc_sortable div.personalblock h3 img{vertical-align:middle;margin-right:10px;} -#stc_frame #stc_sortable div.personalblock h3 span#selunits,#stc_frame #stc_sortable div.personalblock h3 span#selunits_hus{float:right;} diff --git a/apps/storage_charts/img/chart.png b/apps/storage_charts/img/chart.png deleted file mode 100644 index d8a998166419c14c573b2911b2c03aed5c2f0239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 441 zcmV;q0Y?6bP)<h;3K|Lk000e1NJLTq000mG000jN1^@s6?Q>5r0004iNkl<ZD3Ohm zF^dyX9K?U~e7m9%0~UAMcpRd(f*(LoxXy#PakaLy@l*I6B%O^Q+XMtf1Pet$1kuA% z4k6fBC@P}HWZ&4_N({@!=^n#x-W30lZ5owjc>vg!bQRbF4u%jmQ%dJ0eE@d*{r+S$ z8qFF;O+Z<erzPD7POzX5!e(99TMO@R)9Li#cs%|B5CDe5;YmqPmf<#~ln!TEcCjqW zK7a;;!CIc@FKutM0m}^*^c@(7JkJNVkFWZ9S(18nU9Uyk*8u$|WZMaNKby^VVvMIE zaCQ|KLih;mN?K1TodGUnS$0{HBe1UvuIpMMgrm040X^y8vJt4eLP7}FZCg@r*|VJj z@T#kU?HiJA+y2#JPlD}RfLqK)`)xmy^tQ!&9_I7;14)yv7Qm5|(k0-9_fFULr!33f z$Tme$9E&l&2G&;u-2vVKhiu=hs_N_CEfhtu5o3Hz_c{LtuGoHBRn=!$7!$OwanJez jJhFWkxK~xx&xZK}Z4{<Os<94c00000NkvXXu0mjf`|`ti diff --git a/apps/storage_charts/img/loader.gif b/apps/storage_charts/img/loader.gif deleted file mode 100644 index 190582b822618e226f1beed6cee1135fcfaf5984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1849 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 EFV2k%n*aa+ diff --git a/apps/storage_charts/img/move.png b/apps/storage_charts/img/move.png deleted file mode 100644 index afb605ed9a8959c77d76fbdb6d0ddc943439fcde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 457 zcmV;)0XF`LP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0004yNkl<ZIE{_d zziX309LMqZ!IM>Rl|nj*ps1KqikmTm;E-%xG`q$@{0~Z}&N}45{h4$M&mUlP5Q{&G zscDvurJF>om%DquN53wONb?w<?{s{Rd)?>YduA{g^no7BEA4bTPmD2d095tvd?Sf5 z_S)?>s#<!|7(<@tJ!8zPzj{qo9nJx)wTMV5P^;A#jYg>I&=}J^OE8=xCd)EywOV-Z zOMz~;%XB(rGMQ`xch1^x=j)^>3Sx{DMNtZ<Dyqu;hqt#5_m2R$d}F0~xPQdS4|kl1 z2qHoVp%lonjDEk*gWd)&U%Uq3(bG*n?;c<;e7}^05D<}nCJ+(o^*X!nzw+tB7=T;r zS6JJ)%DaPO5)oPYgcu_t!p+7ir+Ny&wZ<x598wh30T(Pg>0<y~umFVMNkk;g^L*(b zU0hMDU%VhVhdDn$&z|4Ywd;*#-k<vNZI9%9)4Lhg|EvUfH!A_W<Cj0F26(p!1V3XI zssX{5BnZLd3R?{bei4Ylr{j;~|9x)&jFSEaKW*{>ChEjc00000NkvXXu0mjfL&nf! diff --git a/apps/storage_charts/js/highCharts-2.2.1/highcharts.min.js b/apps/storage_charts/js/highCharts-2.2.1/highcharts.min.js deleted file mode 100644 index 203d89b6ea..0000000000 --- a/apps/storage_charts/js/highCharts-2.2.1/highcharts.min.js +++ /dev/null @@ -1,202 +0,0 @@ -/* - Highcharts JS v2.2.1 (2012-03-15) - - (c) 2009-2011 Torstein H?nsi - - License: www.highcharts.com/license -*/ -(function(){function L(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function za(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}function S(a,b){return parseInt(a,b||10)}function Ab(a){return typeof a==="string"}function mb(a){return typeof a==="object"}function Fb(a){return Object.prototype.toString.call(a)==="[object Array]"}function Bb(a){return typeof a==="number"}function nb(a){return oa.log(a)/oa.LN10}function cb(a){return oa.pow(10,a)}function Gb(a,b){for(var c= -a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function s(a){return a!==X&&a!==null}function A(a,b,c){var d,e;if(Ab(b))s(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(s(b)&&mb(b))for(d in b)a.setAttribute(d,b[d]);return e}function Hb(a){return Fb(a)?a:[a]}function p(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!=="undefined"&&c!==null)return c}function P(a,b){if(Qb&&b&&b.opacity!==X)b.filter="alpha(opacity="+b.opacity*100+")";L(a.style,b)}function Aa(a, -b,c,d,e){a=x.createElement(a);b&&L(a,b);e&&P(a,{padding:0,border:Ma,margin:0});c&&P(a,c);d&&d.appendChild(a);return a}function pa(a,b){var c=function(){};c.prototype=new a;L(c.prototype,b);return c}function dc(a,b,c,d){var e=Ea.lang,f=isNaN(b=Ba(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?"-":"",c=String(S(a=Ba(+a||0).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+Ba(a-c).toFixed(f).slice(2):"")} -function Na(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function ec(a,b,c,d){var e,c=p(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Kc(a,b){var c=b||[[Rb,[1,2,5,10,20,25,50,100,200,500]],[ob,[1,2,5,10,15,30]],[pb,[1,2,5,10,15,30]],[va,[1,2,3,4,6,8,12]],[Ca,[1,2]],[Ya,[1,2]],[Da,[1,2,3,4,6]],[Za,null]],d=c[c.length-1],e=E[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d= -c[g],e=E[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+E[c[g+1][0]])/2)break;e===E[Za]&&a<5*e&&(f=[1,2,5]);e===E[Za]&&a<5*e&&(f=[1,2,5]);c=ec(a/e,f);return{unitRange:e,count:c,unitName:d[0]}}function Lc(a,b,c,d){var e=[],f={},g=Ea.global.useUTC,h,i=new Date(b),b=a.unitRange,k=a.count;b>=E[ob]&&(i.setMilliseconds(0),i.setSeconds(b>=E[pb]?0:k*Ta(i.getSeconds()/k)));if(b>=E[pb])i[pc](b>=E[va]?0:k*Ta(i[fc]()/k));if(b>=E[va])i[qc](b>=E[Ca]?0:k*Ta(i[gc]()/k));if(b>=E[Ca])i[hc](b>=E[Da]?1:k*Ta(i[db]()/k));b>= -E[Da]&&(i[rc](b>=E[Za]?0:k*Ta(i[qb]()/k)),h=i[rb]());b>=E[Za]&&(h-=h%k,i[sc](h));if(b===E[Ya])i[hc](i[db]()-i[ic]()+p(d,1));d=1;h=i[rb]();for(var j=i.getTime(),l=i[qb](),i=i[db]();j<c;)e.push(j),b===E[Za]?j=sb(h+d*k,0):b===E[Da]?j=sb(h,l+d*k):!g&&(b===E[Ca]||b===E[Ya])?j=sb(h,l,i+d*k*(b===E[Ca]?1:7)):(j+=b*k,b<=E[va]&&j%E[Ca]===0&&(f[j]=Ca)),d++;e.push(j);e.info=L(a,{higherRanks:f,totalRange:b*k});return e}function tc(){this.symbol=this.color=0}function uc(a,b,c,d,e,f,g,h,i){var k=g.x,g=g.y,i=k+c+ -(i?h:-a-h),j=g-b+d+15,l;i<7&&(i=c+k+h);i+a>c+e&&(i-=i+a-(c+e),j=g-b+d-h,l=!0);j<d+5?(j=d+5,l&&g>=j&&g<=j+b&&(j=g+d+h)):j+b>d+f&&(j=d+f-b-h);return{x:i,y:j}}function Mc(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:d});for(e=0;e<c;e++)delete a[e].ss_i}function Sb(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function Ib(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Jb(a){for(var b in a)a[b]&&a[b].destroy&& -a[b].destroy(),delete a[b]}function Tb(a){tb||(tb=Aa(Ra));a&&tb.appendChild(a);tb.innerHTML=""}function jc(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else ca.console&&console.log(c)}function Cb(a){return parseFloat(a.toPrecision(14))}function Kb(a,b){Ub=p(a,b.animation)}function vc(){var a=Ea.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";sb=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,p(c,1),p(g,0),p(h,0),p(i,0))).getTime()};fc=b+"Minutes";gc=b+"Hours"; -ic=b+"Day";db=b+"Date";qb=b+"Month";rb=b+"FullYear";pc=c+"Minutes";qc=c+"Hours";hc=c+"Date";rc=c+"Month";sc=c+"FullYear"}function Sa(){}function wc(a,b){function c(a){function b(a,c){this.pos=a;this.type=c||"";this.isNew=!0;c||this.addLabel()}function c(a){if(a)this.options=a,this.id=a.id;return this}function d(a,b,c,e){this.isNegative=b;this.options=a;this.x=c;this.stack=e;this.alignOptions={align:a.align||(U?b?"left":"right":"center"),verticalAlign:a.verticalAlign||(U?"middle":b?"bottom":"top"), -y:p(a.y,U?4:b?14:-6),x:p(a.x,U?b?-6:6:0)};this.textAlign=a.textAlign||(U?b?"right":"left":"center")}function e(){var a=[],b=[],c;C=M=null;o(B.series,function(e){if(e.visible||!q.ignoreHiddenSeries){var f=e.options,g,h,i,j,k,m,l,n,Y,ea=f.threshold,B,o=[],xc=0;if(R&&ea<=0)ea=f.threshold=null;if(t)f=e.xData,f.length&&(C=Ua(p(C,f[0]),Sb(f)),M=W(p(M,f[0]),Ib(f)));else{var y,r,G,v=e.cropped,Z=e.xAxis.getExtremes(),V=!!e.modifyValue;g=f.stacking;Ha=g==="percent";if(g)k=f.stack,j=e.type+p(k,""),m="-"+j,e.stackKey= -j,h=a[j]||[],a[j]=h,i=b[m]||[],b[m]=i;Ha&&(C=0,M=99);f=e.processedXData;l=e.processedYData;B=l.length;for(c=0;c<B;c++)if(n=f[c],Y=l[c],Y!==null&&Y!==X&&(g?(r=(y=Y<ea)?i:h,G=y?m:j,Y=r[n]=s(r[n])?r[n]+Y:Y,qa[G]||(qa[G]={}),qa[G][n]||(qa[G][n]=new d(u.stackLabels,y,n,k)),qa[G][n].setTotal(Y)):V&&(Y=e.modifyValue(Y)),v||(f[c+1]||n)>=Z.min&&(f[c-1]||n)<=Z.max))if(n=Y.length)for(;n--;)Y[n]!==null&&(o[xc++]=Y[n]);else o[xc++]=Y;!Ha&&o.length&&(C=Ua(p(C,o[0]),Sb(o)),M=W(p(M,o[0]),Ib(o)));s(ea)&&(C>=ea?(C= -ea,Ma=!0):M<ea&&(M=ea,Na=!0))}}})}function f(a,b,c){for(var d,b=Cb(Ta(b/a)*a),c=Cb(Yb(c/a)*a),e=[];b<=c;){e.push(b);b=Cb(b+a);if(b===d)break;d=b}return e}function g(a,b,c,d){var e=[];if(!d)B._minorAutoInterval=null;if(a>=0.5)a=z(a),e=f(a,b,c);else if(a>=0.08){var h=Ta(b),i,j,k,n,m,l;for(i=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];h<c+1&&!l;h++){k=i.length;for(j=0;j<k&&!l;j++)n=nb(cb(h)*i[j]),n>b&&e.push(m),m>c&&(l=!0),m=n}}else if(b=cb(b),c=cb(c),a=u[d?"minorTickInterval":"tickInterval"], -a=p(a==="auto"?null:a,B._minorAutoInterval,(c-b)*(u.tickPixelInterval/(d?5:1))/((d?D/N.length:D)||1)),a=ec(a,null,oa.pow(10,Ta(oa.log(a)/oa.LN10))),e=Vb(f(a,b,c),nb),!d)B._minorAutoInterval=a/5;d||(Oa=a);return e}function h(){var a=[],b,c;if(R){c=N.length;for(b=1;b<c;b++)a=a.concat(g(Ga,N[b-1],N[b],!0))}else for(b=F+(N[0]-F)%Ga;b<=H;b+=Ga)a.push(b);return a}function i(){var a,b=M-C>=fb,c,d,e,f,g,h;t&&fb===X&&!R&&(s(u.min)||s(u.max)?fb=null:(o(B.series,function(a){f=a.xData;for(d=g=a.xIncrement?1: -f.length-1;d>0;d--)if(e=f[d]-f[d-1],c===X||e<c)c=e}),fb=Ua(c*5,M-C)));H-F<fb&&(a=(fb-H+F)/2,a=[F-a,p(u.min,F-a)],b&&(a[2]=C),F=Ib(a),h=[F+fb,p(u.max,F+fb)],b&&(h[2]=M),H=Sb(h),H-F<fb&&(a[0]=H-fb,a[1]=p(u.min,H-fb),F=Ib(a)))}function j(a){var b,c=u.tickInterval,d=u.tickPixelInterval;da?(na=m[t?"xAxis":"yAxis"][u.linkedTo],b=na.getExtremes(),F=p(b.min,b.dataMin),H=p(b.max,b.dataMax),u.type!==na.options.type&&jc(11,1)):(F=p(ba,u.min,C),H=p(ca,u.max,M));R&&(!a&&Ua(F,C)<=0&&jc(10,1),F=nb(F),H=nb(H));ja&& -(ba=F=W(F,H-ja),ca=H,a&&(ja=null));i();if(!Va&&!Ha&&!da&&s(F)&&s(H)){b=H-F||1;if(!s(u.min)&&!s(ba)&&Ea&&(C<0||!Ma))F-=b*Ea;if(!s(u.max)&&!s(ca)&&Ja&&(M>0||!Na))H+=b*Ja}Oa=F===H||F===void 0||H===void 0?1:da&&!c&&d===na.options.tickPixelInterval?na.tickInterval:p(c,Va?1:(H-F)*d/(D||1));t&&!a&&o(B.series,function(a){a.processData(F!==ma||H!==za)});ib();B.beforeSetTickPositions&&B.beforeSetTickPositions();B.postProcessTickInterval&&(Oa=B.postProcessTickInterval(Oa));!V&&!R&&(Wa=oa.pow(10,Ta(oa.log(Oa)/ -oa.LN10)),s(u.tickInterval)||(Oa=ec(Oa,null,Wa,u)));B.tickInterval=Oa;Ga=u.minorTickInterval==="auto"&&Oa?Oa/5:u.minorTickInterval;(N=u.tickPositions||Xa&&Xa.apply(B,[F,H]))||(N=V?(B.getNonLinearTimeTicks||Lc)(Kc(Oa,u.units),F,H,u.startOfWeek,B.ordinalPositions,B.closestPointRange,!0):R?g(Oa,F,H):f(Oa,F,H));if(!da&&(a=N[0],c=N[N.length-1],u.startOnTick?F=a:F>a&&N.shift(),u.endOnTick?H=c:H<c&&N.pop(),gb||(gb={x:0,y:0}),!V&&N.length>gb[w]&&u.alignTicks!==!1))gb[w]=N.length}function k(a){a=(new c(a)).render(); -ta.push(a);return a}function l(){var a=u.title,d=u.stackLabels,e=u.alternateGridColor,f=u.lineWidth,g,i,j=m.hasRendered&&s(ma)&&!isNaN(ma),n=(g=B.series.length&&s(F)&&s(H))||p(u.showEmpty,!0),Y,q;if(g||da)if(Ga&&!Va&&o(h(),function(a){va[a]||(va[a]=new b(a,"minor"));j&&va[a].isNew&&va[a].render(null,!0);va[a].isActive=!0;va[a].render()}),o(N.slice(1).concat([N[0]]),function(a,c){c=c===N.length-1?0:c+1;if(!da||a>=F&&a<=H)Pa[a]||(Pa[a]=new b(a)),j&&Pa[a].isNew&&Pa[a].render(c,!0),Pa[a].isActive=!0, -Pa[a].render(c)}),e&&o(N,function(a,b){if(b%2===0&&a<H)Da[a]||(Da[a]=new c),Y=a,q=N[b+1]!==X?N[b+1]:H,Da[a].options={from:R?cb(Y):Y,to:R?cb(q):q,color:e},Da[a].render(),Da[a].isActive=!0}),!B._addedPlotLB)o((u.plotLines||[]).concat(u.plotBands||[]),function(a){k(a)}),B._addedPlotLB=!0;o([Pa,va,Da],function(a){for(var b in a)a[b].isActive?a[b].isActive=!1:(a[b].destroy(),delete a[b])});f&&(g=x+(y?A:0)+T,i=ra-Lb-(y?hb:0)+T,g=I.crispLine([wa,G?x:g,G?i:E,fa,G?sa-Zb:g,G?i:ra-Lb],f),$?$.animate({d:g}): -$=I.path(g).attr({stroke:u.lineColor,"stroke-width":f,zIndex:7}).add(),$[n?"show":"hide"]());if(v&&n)n=G?x:E,f=S(a.style.fontSize||12),n={low:n+(G?0:D),middle:n+D/2,high:n+(G?D:0)}[a.align],f=(G?E+hb:x)+(G?1:-1)*(y?-1:1)*Ya+(r===2?f:0),v[v.isNew?"attr":"animate"]({x:G?n:f+(y?A:0)+T+(a.x||0),y:G?f-(y?hb:0)+T:n+(a.y||0)}),v.isNew=!1;if(d&&d.enabled){var t,yc,d=B.stackTotalGroup;if(!d)B.stackTotalGroup=d=I.g("stack-labels").attr({visibility:eb,zIndex:6}).translate(O,J).add();for(t in qa)for(yc in a= -qa[t],a)a[yc].render(d)}B.isDirty=!1}function n(a){for(var b=ta.length;b--;)ta[b].id===a&&ta[b].destroy()}var t=a.isX,y=a.opposite,G=U?!t:t,r=G?y?0:2:y?1:3,qa={},u=K(t?$b:kc,[Nc,Oc,zc,Pc][r],a),B=this,v,Z=u.type,V=Z==="datetime",R=Z==="logarithmic",T=u.offset||0,w=t?"x":"y",D=0,ua,ia,bb,jb,x,E,A,hb,Lb,Zb,Mb,ib,P,Q,bc,$,C,M,fb=u.minRange||u.maxZoom,ja=u.range,ba,ca,Aa,Ca,H=null,F=null,ma,za,Ea=u.minPadding,Ja=u.maxPadding,Ka=0,da=s(u.linkedTo),na,Ma,Na,Ha,Z=u.events,Sa,ta=[],Oa,Ga,Wa,N,Xa=u.tickPositioner, -Pa={},va={},Da={},Fa,La,Ya,Va=u.categories,db=u.labels.formatter||function(){var a=this.value,b=this.dateTimeLabelFormat;return b?ac(b,a):Oa%1E6===0?a/1E6+"M":Oa%1E3===0?a/1E3+"k":!Va&&a>=1E3?dc(a,0):a},Ra=G&&u.labels.staggerLines,ya=u.reversed,Ia=Va&&u.tickmarkPlacement==="between"?0.5:0;b.prototype={addLabel:function(){var a=this.pos,b=u.labels,c=Va&&G&&Va.length&&!b.step&&!b.staggerLines&&!b.rotation&&ka/Va.length||!G&&ka/2,d=a===N[0],e=a===N[N.length-1],f=Va&&s(Va[a])?Va[a]:a,g=this.label,h=N.info, -i;V&&h&&(i=u.dateTimeLabelFormats[h.higherRanks[a]||h.unitName]);this.isFirst=d;this.isLast=e;a=db.call({axis:B,chart:m,isFirst:d,isLast:e,dateTimeLabelFormat:i,value:R?Cb(cb(f)):f});c=c&&{width:W(1,z(c-2*(b.padding||10)))+ga};c=L(c,b.style);s(g)?g&&g.attr({text:a}).css(c):this.label=s(a)&&b.enabled?I.text(a,0,0,b.useHTML).attr({align:b.align,rotation:b.rotation}).css(c).add(Q):null},getLabelSize:function(){var a=this.label;return a?(this.labelBBox=a.getBBox())[G?"height":"width"]:0},getLabelSides:function(){var a= -u.labels,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.align]-a.x;return[-a,b-a]},handleOverflow:function(a){var b=!0,c=this.isFirst,d=this.isLast,e=this.label,f=e.x;if(c||d){var g=this.getLabelSides(),h=g[0],g=g[1],i=m.plotLeft,j=i+B.len,k=(a=Pa[N[a+(c?1:-1)]])&&a.label.x+a.getLabelSides()[c?0:1];c&&!ya||d&&ya?f+h<i&&(f=i-h,a&&f+g>k&&(b=!1)):f+g>j&&(f=j-g,a&&f+h<k&&(b=!1));e.x=f}return b},render:function(a,b){var c=this.type,d=this.label,e=this.pos,f=u.labels,g=this.gridLine,h=c?c+"Grid": -"grid",i=c?c+"Tick":"tick",j=u[h+"LineWidth"],k=u[h+"LineColor"],n=u[h+"LineDashStyle"],m=u[i+"Length"],h=u[i+"Width"]||0,l=u[i+"Color"],Y=u[i+"Position"],i=this.mark,q=f.step,ea=b&&Za||ra,qa=!0,o;o=G?Mb(e+Ia,null,null,b)+bb:x+T+(y?(b&&$a||sa)-Zb-x:0);ea=G?ea-Lb+T-(y?hb:0):ea-Mb(e+Ia,null,null,b)-bb;if(j){e=P(e+Ia,j,b);if(g===X){g={stroke:k,"stroke-width":j};if(n)g.dashstyle=n;if(!c)g.zIndex=1;this.gridLine=g=j?I.path(e).attr(g).add(bc):null}!b&&g&&e&&g.animate({d:e})}if(h)Y==="inside"&&(m=-m),y&& -(m=-m),c=I.crispLine([wa,o,ea,fa,o+(G?0:-m),ea+(G?m:0)],h),i?i.animate({d:c}):this.mark=I.path(c).attr({stroke:l,"stroke-width":h}).add(Q);if(d&&!isNaN(o))o=o+f.x-(Ia&&G?Ia*ia*(ya?-1:1):0),ea=ea+f.y-(Ia&&!G?Ia*ia*(ya?1:-1):0),s(f.y)||(ea+=S(d.styles.lineHeight)*0.9-d.getBBox().height/2),Ra&&(ea+=a/(q||1)%Ra*16),d.x=o,d.y=ea,this.isFirst&&!p(u.showFirstLabel,1)||this.isLast&&!p(u.showLastLabel,1)?qa=!1:!Ra&&G&&f.overflow==="justify"&&!this.handleOverflow(a)&&(qa=!1),q&&a%q&&(qa=!1),qa?(d[this.isNew? -"attr":"animate"]({x:d.x,y:d.y}),d.show(),this.isNew=!1):d.hide()},destroy:function(){Jb(this)}};c.prototype={render:function(){var a=this,b=(B.pointRange||0)/2,c=a.options,d=c.label,e=a.label,f=c.width,g=c.to,h=c.from,i=c.value,j,k=c.dashStyle,n=a.svgElem,m=[],l,Y,u=c.color;Y=c.zIndex;var ea=c.events;R&&(h=nb(h),g=nb(g),i=nb(i));if(f){if(m=P(i,f),b={stroke:u,"stroke-width":f},k)b.dashstyle=k}else if(s(h)&&s(g))h=W(h,F-b),g=Ua(g,H+b),j=P(g),(m=P(h))&&j?m.push(j[4],j[5],j[1],j[2]):m=null,b={fill:u}; -else return;if(s(Y))b.zIndex=Y;if(n)m?n.animate({d:m},null,n.onGetPath):(n.hide(),n.onGetPath=function(){n.show()});else if(m&&m.length&&(a.svgElem=n=I.path(m).attr(b).add(),ea))for(l in k=function(b){n.on(b,function(c){ea[b].apply(a,[c])})},ea)k(l);if(d&&s(d.text)&&m&&m.length&&A>0&&hb>0){d=K({align:G&&j&&"center",x:G?!j&&4:10,verticalAlign:!G&&j&&"middle",y:G?j?16:10:j?6:-4,rotation:G&&!j&&90},d);if(!e)a.label=e=I.text(d.text,0,0).attr({align:d.textAlign||d.align,rotation:d.rotation,zIndex:Y}).css(d.style).add(); -j=[m[1],m[4],p(m[6],m[1])];m=[m[2],m[5],p(m[7],m[2])];l=Sb(j);Y=Sb(m);e.align(d,!1,{x:l,y:Y,width:Ib(j)-l,height:Ib(m)-Y});e.show()}else e&&e.hide();return a},destroy:function(){Jb(this);Gb(ta,this)}};d.prototype={destroy:function(){Jb(this)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options.formatter.call(this);this.label?this.label.attr({text:b,visibility:ab}):this.label=m.renderer.text(b,0,0).css(this.options.style).attr({align:this.textAlign,rotation:this.options.rotation, -visibility:ab}).add(a)},setOffset:function(a,b){var c=this.isNegative,d=B.translate(this.total,0,0,0,1),e=B.translate(0),e=Ba(d-e),f=m.xAxis[0].translate(this.x)+a,g=m.plotHeight,c={x:U?c?d:d-e:f,y:U?g-f-b:c?g-d-e:g-d,width:U?e:b,height:U?b:e};this.label&&this.label.align(this.alignOptions,null,c).attr({visibility:eb})}};Mb=function(a,b,c,d,e){var f=1,g=0,h=d?jb:ia,d=d?ma:F,e=u.ordinal||R&&e;h||(h=ia);c&&(f*=-1,g=D);ya&&(f*=-1,g-=f*D);b?(ya&&(a=D-a),a=a/h+d,e&&(a=B.lin2val(a))):(e&&(a=B.val2lin(a)), -a=f*(a-d)*h+g+f*Ka);return a};P=function(a,b,c){var d,e,f,a=Mb(a,null,null,c),g=c&&Za||ra,h=c&&$a||sa,i,c=e=z(a+bb);d=f=z(g-a-bb);if(isNaN(a))i=!0;else if(G){if(d=E,f=g-Lb,c<x||c>x+A)i=!0}else if(c=x,e=h-Zb,d<E||d>E+hb)i=!0;return i?null:I.crispLine([wa,c,d,fa,e,f],b||0)};ib=function(){var a=H-F,b=0,c,d;if(t)da?b=na.pointRange:o(B.series,function(a){b=W(b,a.pointRange);d=a.closestPointRange;!a.noSharedTooltip&&s(d)&&(c=s(c)?Ua(c,d):d)}),B.pointRange=b,B.closestPointRange=c;jb=ia;B.translationSlope= -ia=D/(a+b||1);bb=G?x:Lb;Ka=ia*(b/2)};xa.push(B);m[t?"xAxis":"yAxis"].push(B);U&&t&&ya===X&&(ya=!0);L(B,{addPlotBand:k,addPlotLine:k,adjustTickAmount:function(){if(gb&&gb[w]&&!V&&!Va&&!da&&u.alignTicks!==!1){var a=Fa,b=N.length;Fa=gb[w];if(b<Fa){for(;N.length<Fa;)N.push(Cb(N[N.length-1]+Oa));ia*=(b-1)/(Fa-1);H=N[N.length-1]}if(s(a)&&Fa!==a)B.isDirty=!0}},categories:Va,getExtremes:function(){return{min:R?Cb(cb(F)):F,max:R?Cb(cb(H)):H,dataMin:C,dataMax:M,userMin:ba,userMax:ca}},getPlotLinePath:P,getThreshold:function(a){var b= -R?cb(F):F,c=R?cb(H):H;b>a||a===null?a=b:c<a&&(a=c);return Mb(a,0,1,0,1)},isXAxis:t,options:u,plotLinesAndBands:ta,getOffset:function(){var a=B.series.length&&s(F)&&s(H),c=a||p(u.showEmpty,!0),d=0,e,f=0,g=u.title,h=u.labels,i=[-1,1,1,-1][r],j;Q||(Q=I.g("axis").attr({zIndex:7}).add(),bc=I.g("grid").attr({zIndex:u.gridZIndex||1}).add());La=0;if(a||da)o(N,function(a){Pa[a]?Pa[a].addLabel():Pa[a]=new b(a)}),o(N,function(a){if(r===0||r===2||{1:"left",3:"right"}[r]===h.align)La=W(Pa[a].getLabelSize(),La)}), -Ra&&(La+=(Ra-1)*16);else for(j in Pa)Pa[j].destroy(),delete Pa[j];if(g&&g.text){if(!v)v=B.axisTitle=I.text(g.text,0,0,g.useHTML).attr({zIndex:7,rotation:g.rotation||0,align:g.textAlign||{low:"left",middle:"center",high:"right"}[g.align]}).css(g.style).add(),v.isNew=!0;if(c)d=v.getBBox()[G?"height":"width"],f=p(g.margin,G?5:10),e=g.offset;v[c?"show":"hide"]()}T=i*p(u.offset,pa[r]);Ya=p(e,La+f+(r!==2&&La&&i*u.labels[G?"y":"x"]));pa[r]=W(pa[r],Ya+d+i*T)},render:l,setAxisSize:function(){var a=u.offsetLeft|| -0,b=u.offsetRight||0;x=p(u.left,O+a);E=p(u.top,J);A=p(u.width,ka-a+b);hb=p(u.height,la);Lb=ra-hb-E;Zb=sa-A-x;D=G?A:hb;B.left=x;B.top=E;B.len=D},setAxisTranslation:ib,setCategories:function(b,c){B.categories=a.categories=Va=b;o(B.series,function(a){a.translate();a.setTooltipPoints(!0)});B.isDirty=!0;p(c,!0)&&m.redraw()},setExtremes:function(a,b,c,d,e){c=p(c,!0);e=L(e,{min:a,max:b});aa(B,"setExtremes",e,function(){ba=a;ca=b;B.isDirtyExtremes=!0;c&&m.redraw(d)})},setScale:function(){var a,b,c,d;ma=F; -za=H;ua=D;D=G?A:hb;d=D!==ua;o(B.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)c=!0});if(d||c||da||ba!==Aa||ca!==Ca){e();j();Aa=ba;Ca=ca;if(!t)for(a in qa)for(b in qa[a])qa[a][b].cum=qa[a][b].total;if(!B.isDirty)B.isDirty=d||F!==ma||H!==za}},setTickPositions:j,translate:Mb,redraw:function(){ub.resetTracker&&ub.resetTracker();l();o(ta,function(a){a.render()});o(B.series,function(a){a.isDirty=!0})},removePlotBand:n,removePlotLine:n,reversed:ya,setTitle:function(a,b){u.title=K(u.title, -a);v=v.destroy();B.isDirty=!0;p(b,!0)&&m.redraw()},series:[],stacks:qa,destroy:function(){var a;Qa(B);for(a in qa)Jb(qa[a]),qa[a]=null;if(B.stackTotalGroup)B.stackTotalGroup=B.stackTotalGroup.destroy();o([Pa,va,Da,ta],function(a){Jb(a)});o([$,Q,bc,v],function(a){a&&a.destroy()});$=Q=bc=v=null}});for(Sa in Z)ha(B,Sa,Z[Sa]);if(R)B.val2lin=nb,B.lin2val=cb}function d(a){function b(){var c=this.points||Hb(this),d=c[0].series,e;e=[d.tooltipHeaderFormatter(c[0].key)];o(c,function(a){d=a.series;e.push(d.tooltipFormatter&& -d.tooltipFormatter(a)||a.point.tooltipFormatter(d.tooltipOptions.pointFormat))});e.push(a.footerFormat||"");return e.join("")}function c(a,b){l=n?a:(2*l+a)/3;q=n?b:(q+b)/2;t.attr({x:l,y:q});lb=Ba(a-l)>1||Ba(b-q)>1?function(){c(a,b)}:null}function d(){if(!n){var a=m.hoverPoints;t.hide();a&&o(a,function(a){a.setState()});m.hoverPoints=null;n=!0}}var e,f=a.borderWidth,g=a.crosshairs,h=[],i=a.style,j=a.shared,k=S(i.padding),n=!0,l=0,q=0;i.padding=0;var t=I.label("",0,0,null,null,null,a.useHTML).attr({padding:k, -fill:a.backgroundColor,"stroke-width":f,r:a.borderRadius,zIndex:8}).css(i).hide().add();Fa||t.shadow(a.shadow);return{shared:j,refresh:function(f){var i,k,l,q,r={},y=[];l=f.tooltipPos;i=a.formatter||b;var r=m.hoverPoints,v;j&&(!f.series||!f.series.noSharedTooltip)?(q=0,r&&o(r,function(a){a.setState()}),m.hoverPoints=f,o(f,function(a){a.setState(ta);q+=a.plotY;y.push(a.getLabelConfig())}),k=f[0].plotX,q=z(q)/f.length,r={x:f[0].category},r.points=y,f=f[0]):r=f.getLabelConfig();r=i.call(r);e=f.series; -k=p(k,f.plotX);q=p(q,f.plotY);i=z(l?l[0]:U?ka-q:k);k=z(l?l[1]:U?la-k:q);l=j||!e.isCartesian||e.tooltipOutsidePlot||Db(i,k);r===!1||!l?d():(n&&(t.show(),n=!1),t.attr({text:r}),v=a.borderColor||f.color||e.color||"#606060",t.attr({stroke:v}),l=uc(t.width,t.height,O,J,ka,la,{x:i,y:k},p(a.distance,12),U),c(z(l.x),z(l.y)));if(g){g=Hb(g);var R;l=g.length;for(var Z;l--;)if(R=f.series[l?"yAxis":"xAxis"],g[l]&&R)if(R=R.getPlotLinePath(l?p(f.stackY,f.y):f.x,1),h[l])h[l].attr({d:R,visibility:eb});else{Z={"stroke-width":g[l].width|| -1,stroke:g[l].color||"#C0C0C0",zIndex:g[l].zIndex||2};if(g[l].dashStyle)Z.dashstyle=g[l].dashStyle;h[l]=I.path(R).attr(Z).add()}}aa(m,"tooltipRefresh",{text:r,x:i+O,y:k+J,borderColor:v})},hide:d,hideCrosshairs:function(){o(h,function(a){a&&a.hide()})},destroy:function(){o(h,function(a){a&&a.destroy()});t&&(t=t.destroy())}}}function e(a){function b(a){var c,d,e,a=a||ca.event;if(!a.target)a.target=a.srcElement;if(a.originalEvent)a=a.originalEvent;if(a.event)a=a.event;c=a.touches?a.touches.item(0):a; -ya=Ac(D);d=ya.left;e=ya.top;Qb?(d=a.x,c=a.y):(d=c.pageX-d,c=c.pageY-e);return L(a,{chartX:z(d),chartY:z(c)})}function c(a){var b={xAxis:[],yAxis:[]};o(xa,function(c){var d=c.translate,e=c.isXAxis;b[e?"xAxis":"yAxis"].push({axis:c,value:d((U?!e:e)?a.chartX-O:la-a.chartY+J,!0)})});return b}function e(){var a=m.hoverSeries,b=m.hoverPoint;if(b)b.onMouseOut();if(a)a.onMouseOut();vb&&(vb.hide(),vb.hideCrosshairs());ob=null}function f(){if(n){var a={xAxis:[],yAxis:[]},b=n.getBBox(),c=b.x-O,d=b.y-J;k&&(o(xa, -function(e){if(e.options.zoomEnabled!==!1){var f=e.translate,g=e.isXAxis,h=U?!g:g,i=f(h?c:la-d-b.height,!0,0,0,1),f=f(h?c+b.width:la-d,!0,0,0,1);a[g?"xAxis":"yAxis"].push({axis:e,min:Ua(i,f),max:W(i,f)})}}),aa(m,"selection",a,zb));n=n.destroy()}P(D,{cursor:"auto"});m.mouseIsDown=Da=k=!1;Qa(x,Ga?"touchend":"mouseup",f)}function g(a){var b=s(a.pageX)?a.pageX:a.page.x,a=s(a.pageX)?a.pageY:a.page.y;ya&&!Db(b-ya.left-O,a-ya.top-J)&&e()}function h(){e();ya=null}var i,j,k,n,l=Fa?"":q.zoomType,t=/x/.test(l), -r=/y/.test(l),y=t&&!U||r&&U,p=r&&!U||t&&U;if(!db)m.trackerGroup=db=I.g("tracker").attr({zIndex:9}).add();if(a.enabled)m.tooltip=vb=d(a),Bb=setInterval(function(){lb&&lb()},32);(function(){D.onmousedown=function(a){a=b(a);!Ga&&a.preventDefault&&a.preventDefault();m.mouseIsDown=Da=!0;m.mouseDownX=i=a.chartX;j=a.chartY;ha(x,Ga?"touchend":"mouseup",f)};var d=function(c){if(!c||!(c.touches&&c.touches.length>1)){c=b(c);if(!Ga)c.returnValue=!1;var d=c.chartX,e=c.chartY,f=!Db(d-O,e-J);Ga&&c.type==="touchstart"&& -(A(c.target,"isTracker")?m.runTrackerClick||c.preventDefault():!kb&&!f&&c.preventDefault());f&&(d<O?d=O:d>O+ka&&(d=O+ka),e<J?e=J:e>J+la&&(e=J+la));if(Da&&c.type!=="touchstart"){if(k=Math.sqrt(Math.pow(i-d,2)+Math.pow(j-e,2)),k>10){var g=Db(i-O,j-J);if(Nb&&(t||r)&&g)n||(n=I.rect(O,J,y?1:ka,p?1:la,0).attr({fill:q.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add());n&&y&&(c=d-i,n.attr({width:Ba(c),x:(c>0?0:c)+i}));n&&p&&(e-=j,n.attr({height:Ba(e),y:(e>0?0:e)+j}));g&&!n&&q.panning&&m.pan(d)}}else if(!f){var h, -d=m.hoverPoint,e=m.hoverSeries,l,o,g=sa,R=U?c.chartY:c.chartX-O;if(vb&&a.shared&&(!e||!e.noSharedTooltip)){h=[];l=Q.length;for(o=0;o<l;o++)if(Q[o].visible&&Q[o].options.enableMouseTracking!==!1&&!Q[o].noSharedTooltip&&Q[o].tooltipPoints.length)c=Q[o].tooltipPoints[R],c._dist=Ba(R-c.plotX),g=Ua(g,c._dist),h.push(c);for(l=h.length;l--;)h[l]._dist>g&&h.splice(l,1);if(h.length&&h[0].plotX!==ob)vb.refresh(h),ob=h[0].plotX}if(e&&e.tracker&&(c=e.tooltipPoints[R])&&c!==d)c.onMouseOver()}return f||!Nb}};D.onmousemove= -d;ha(D,"mouseleave",h);ha(x,"mousemove",g);D.ontouchstart=function(a){if(t||r)D.onmousedown(a);d(a)};D.ontouchmove=d;D.ontouchend=function(){k&&e()};D.onclick=function(a){var d=m.hoverPoint,a=b(a);a.cancelBubble=!0;if(!k)if(d&&(A(a.target,"isTracker")||A(a.target.parentNode,"isTracker"))){var e=d.plotX,f=d.plotY;L(d,{pageX:ya.left+O+(U?ka-f:e),pageY:ya.top+J+(U?la-e:f)});aa(d.series,"click",L(a,{point:d}));d.firePointEvent("click",a)}else L(a,c(a)),Db(a.chartX-O,a.chartY-J)&&aa(m,"click",a);k=!1}})(); -L(this,{zoomX:t,zoomY:r,resetTracker:e,normalizeMouseEvent:b,destroy:function(){if(m.trackerGroup)m.trackerGroup=db=m.trackerGroup.destroy();Qa(D,"mouseleave",h);Qa(x,"mousemove",g);D.onclick=D.onmousedown=D.onmousemove=D.ontouchstart=D.ontouchend=D.ontouchmove=null}})}function f(a){var b=a.type||q.type||q.defaultSeriesType,c=Ha[b],d=m.hasRendered;if(d)if(U&&b==="column")c=Ha.bar;else if(!U&&b==="bar")c=Ha.column;b=new c;b.init(m,a);!d&&b.inverted&&(U=!0);if(b.isCartesian)Nb=b.isCartesian;Q.push(b); -return b}function g(){q.alignTicks!==!1&&o(xa,function(a){a.adjustTickAmount()});gb=null}function h(a){var b=m.isDirtyLegend,c,d=m.isDirtyBox,e=Q.length,f=e,h=m.clipRect;for(Kb(a,m);f--;)if(a=Q[f],a.isDirty&&a.options.stacking){c=!0;break}if(c)for(f=e;f--;)if(a=Q[f],a.options.stacking)a.isDirty=!0;o(Q,function(a){a.isDirty&&a.options.legendType==="point"&&(b=!0)});if(b&&Xa.renderLegend)Xa.renderLegend(),m.isDirtyLegend=!1;Nb&&(La||(gb=null,o(xa,function(a){a.setScale()})),g(),Wb(),o(xa,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes= -!1,aa(a,"afterSetExtremes",a.getExtremes());if(a.isDirty||d)a.redraw(),d=!0}));d&&(qb(),h&&(Ob(h),h.animate({width:m.plotSizeX,height:m.plotSizeY+1})));o(Q,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});ub&&ub.resetTracker&&ub.resetTracker();I.draw();aa(m,"redraw")}function i(){var a=v.xAxis||{},b=v.yAxis||{},a=Hb(a);o(a,function(a,b){a.index=b;a.isX=!0});b=Hb(b);o(b,function(a,b){a.index=b});a=a.concat(b);o(a,function(a){new c(a)});g()}function k(){var a=Ea.lang,b=q.resetZoomButton, -c=b.theme,d=c.states,e=b.relativeTo==="chart"?null:{x:O,y:J,width:ka,height:la};m.resetZoomButton=I.button(a.resetZoom,null,null,Fb,c,d&&d.hover).attr({align:b.position.align,title:a.resetZoomTitle}).add().align(b.position,!1,e)}function j(a,b){$=K(v.title,a);ja=K(v.subtitle,b);o([["title",a,$],["subtitle",b,ja]],function(a){var b=a[0],c=m[b],d=a[1],a=a[2];c&&d&&(c=c.destroy());a&&a.text&&!c&&(m[b]=I.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":Ia+b,zIndex:a.zIndex||4}).css(a.style).add().align(a, -!1,ib))})}function l(){Ja=q.renderTo;na=Ia+lc++;Ab(Ja)&&(Ja=x.getElementById(Ja));Ja||jc(13,!0);Ja.innerHTML="";Ja.offsetWidth||(C=Ja.cloneNode(0),P(C,{position:wb,top:"-9999px",display:""}),x.body.appendChild(C));za=(C||Ja).offsetWidth;Ca=(C||Ja).offsetHeight;m.chartWidth=sa=q.width||za||600;m.chartHeight=ra=q.height||(Ca>19?Ca:400);m.container=D=Aa(Ra,{className:Ia+"container"+(q.className?" "+q.className:""),id:na},L({position:mc,overflow:ab,width:sa+ga,height:ra+ga,textAlign:"left",lineHeight:"normal"}, -q.style),C||Ja);m.renderer=I=q.forExport?new Eb(D,sa,ra,!0):new Xb(D,sa,ra);Fa&&I.create(m,D,sa,ra);var a,b;Bc&&D.getBoundingClientRect&&(a=function(){P(D,{left:0,top:0});b=D.getBoundingClientRect();P(D,{left:-(b.left-S(b.left))+ga,top:-(b.top-S(b.top))+ga})},a(),ha(ca,"resize",a),ha(m,"destroy",function(){Qa(ca,"resize",a)}))}function n(){function a(c){var d=q.width||Ja.offsetWidth,e=q.height||Ja.offsetHeight,c=c?c.target:ca;if(d&&e&&(c===ca||c===x)){if(d!==za||e!==Ca)clearTimeout(b),b=setTimeout(function(){tb(d, -e,!1)},100);za=d;Ca=e}}var b;ha(ca,"resize",a);ha(m,"destroy",function(){Qa(ca,"resize",a)})}function t(){m&&aa(m,"endResize",null,function(){La-=1})}function r(){for(var a=U||q.inverted||q.type==="bar"||q.defaultSeriesType==="bar",b=v.series,c=b&&b.length;!a&&c--;)b[c].type==="bar"&&(a=!0);m.inverted=U=a}function Z(){var a=v.labels,b=v.credits,c;j();Xa=m.legend=new Rb;o(xa,function(a){a.setScale()});Wb();o(xa,function(a){a.setTickPositions(!0)});g();Wb();qb();Nb&&o(xa,function(a){a.render()});if(!m.seriesGroup)m.seriesGroup= -I.g("series-group").attr({zIndex:3}).add();o(Q,function(a){a.translate();a.setTooltipPoints();a.render()});a.items&&o(a.items,function(){var b=L(a.style,this.style),c=S(b.left)+O,d=S(b.top)+J+12;delete b.left;delete b.top;I.text(this.html,c,d).attr({zIndex:2}).css(b).add()});if(b.enabled&&!m.credits)c=b.href,m.credits=I.text(b.text,0,0).on("click",function(){if(c)location.href=c}).attr({align:b.position.align,zIndex:8}).css(b.style).add().align(b.position);m.hasRendered=!0}function V(){if(!Pb&&ca== -ca.top&&x.readyState!=="complete"||Fa&&!ca.canvg)Fa?Cc.push(V,v.global.canvasToolsURL):x.attachEvent("onreadystatechange",function(){x.detachEvent("onreadystatechange",V);x.readyState==="complete"&&V()});else{l();aa(m,"init");if(Highcharts.RangeSelector&&v.rangeSelector.enabled)m.rangeSelector=new Highcharts.RangeSelector(m);rb();sb();r();i();o(v.series||[],function(a){f(a)});if(Highcharts.Scroller&&(v.navigator.enabled||v.scrollbar.enabled))m.scroller=new Highcharts.Scroller(m);m.render=Z;m.tracker= -ub=new e(v.tooltip);Z();I.draw();b&&b.apply(m,[m]);o(m.callbacks,function(a){a.apply(m,[m])});C&&(Ja.appendChild(D),Tb(C));aa(m,"load")}}var v,y=a.series;a.series=null;v=K(Ea,a);v.series=a.series=y;var q=v.chart,y=q.margin,y=mb(y)?y:[y,y,y,y],T=p(q.marginTop,y[0]),w=p(q.marginRight,y[1]),E=p(q.marginBottom,y[2]),bb=p(q.marginLeft,y[3]),ia=q.spacingTop,ua=q.spacingRight,R=q.spacingBottom,jb=q.spacingLeft,ib,$,ja,J,ba,M,O,pa,Ja,C,D,na,za,Ca,sa,ra,$a,Za,ma,Na,Sa,da,m=this,kb=(y=q.events)&&!!y.click, -va,Db,vb,Da,xb,pb,Ya,la,ka,ub,db,Xa,Wa,yb,ya,Nb=q.showAxes,La=0,xa=[],gb,Q=[],U,I,lb,Bb,ob,qb,Wb,rb,sb,tb,zb,Fb,Rb=function(){function a(b,c){var d=b.legendItem,e=b.legendLine,g=b.legendSymbol,h=q.color,i=c?f.itemStyle.color:h,h=c?b.color:h;d&&d.css({fill:i});e&&e.attr({stroke:h});g&&g.attr({stroke:h,fill:h})}function b(a){var c=a.legendItem,d=a.legendLine,e=a._legendItemPos,f=e[0],e=e[1],g=a.legendSymbol,a=a.checkbox;c&&c.attr({x:r?f:Wa-f,y:e});d&&d.translate(r?f:Wa-f,e-4);g&&(c=f+g.xOff,g.attr({x:r? -c:Wa-c,y:e+g.yOff}));if(a)a.x=f,a.y=e}function c(){o(j,function(a){var b=a.checkbox,c=A.alignAttr;b&&P(b,{left:c.translateX+a.legendItemWidth+b.x-40+ga,top:c.translateY+b.y-11+ga})})}function d(b){var c,e,j,k,m=b.legendItem;k=b.series||b;var o=k.options,v=o&&o.borderWidth||0;if(!m){k=/^(bar|pie|area|column)$/.test(k.type);b.legendItem=m=I.text(f.labelFormatter.call(b),0,0,f.useHTML).css(b.visible?n:q).on("mouseover",function(){b.setState(ta);m.css(l)}).on("mouseout",function(){m.css(b.visible?n:q); -b.setState()}).on("click",function(){var a=function(){b.setVisible()};b.firePointEvent?b.firePointEvent("legendItemClick",null,a):aa(b,"legendItemClick",null,a)}).attr({align:r?"left":"right",zIndex:2}).add(A);if(!k&&o&&o.lineWidth){var u={"stroke-width":o.lineWidth,zIndex:2};if(o.dashStyle)u.dashstyle=o.dashStyle;b.legendLine=I.path([wa,(-h-i)*(r?1:-1),0,fa,-i*(r?1:-1),0]).attr(u).add(A)}if(k)j=I.rect(c=-h-i,e=-11,h,12,2).attr({zIndex:3}).add(A),r||(c+=h);else if(o&&o.marker&&o.marker.enabled)j= -o.marker.radius,j=I.symbol(b.symbol,c=-h/2-i-j,e=-4-j,2*j,2*j).attr(b.pointAttr[Ka]).attr({zIndex:3}).add(A),r||(c+=h/2);if(j)j.xOff=c+v%2/2,j.yOff=e+v%2/2;b.legendSymbol=j;a(b,b.visible);if(o&&o.showCheckbox)b.checkbox=Aa("input",{type:"checkbox",checked:b.selected,defaultChecked:b.selected},f.itemCheckboxStyle,D),ha(b.checkbox,"click",function(a){aa(b,"checkboxClick",{checked:a.target.checked},function(){b.select()})})}c=m.getBBox();e=b.legendItemWidth=f.itemWidth||h+i+c.width+t;w=c.height;if(g&& -s-V+e>(J||sa-2*t-V))s=V,z+=y+w+p;!g&&z+f.y+w>ra-ia-R&&(z=T,s+=Z,Z=0);Z=W(Z,e);x=W(x,z+p);b._legendItemPos=[s,z];g?s+=e:z+=y+w+p;C=J||W(s-V+(g?0:e),C)}function e(){s=V;z=T;x=C=0;A||(A=I.g("legend").attr({zIndex:7}).add());j=[];o(M,function(a){var b=a.options;b.showInLegend&&(j=j.concat(a.legendItems||(b.legendType==="point"?a.data:a)))});Mc(j,function(a,b){return(a.options.legendIndex||0)-(b.options.legendIndex||0)});jb&&j.reverse();o(j,d);Wa=J||C;yb=x-v+w;if(E||bb){Wa+=2*t;yb+=2*t;if(ua){if(Wa>0&& -yb>0)ua[ua.isNew?"attr":"animate"](ua.crisp(null,null,null,Wa,yb)),ua.isNew=!1}else ua=I.rect(0,0,Wa,yb,f.borderRadius,E||0).attr({stroke:f.borderColor,"stroke-width":E||0,fill:bb||Ma}).add(A).shadow(f.shadow),ua.isNew=!0;ua[j.length?"show":"hide"]()}o(j,b);for(var a=["left","right","top","bottom"],g,h=4;h--;)g=a[h],k[g]&&k[g]!=="auto"&&(f[h<2?"align":"verticalAlign"]=g,f[h<2?"x":"y"]=S(k[g])*(h%2?-1:1));j.length&&A.align(L(f,{width:Wa,height:yb}),!0,ib);La||c()}var f=m.options.legend;if(f.enabled){var g= -f.layout==="horizontal",h=f.symbolWidth,i=f.symbolPadding,j,k=f.style,n=f.itemStyle,l=f.itemHoverStyle,q=K(n,f.itemHiddenStyle),t=f.padding||S(k.padding),r=!f.rtl,y=f.itemMarginTop||0,p=f.itemMarginBottom||0,v=18,Z=0,V=4+t+h+i,T=t+y+v-5,s,z,x,w=0,ua,E=f.borderWidth,bb=f.backgroundColor,A,C,J=f.width,M=m.series,jb=f.reversed;e();ha(m,"endResize",c);return{colorizeItem:a,destroyItem:function(a){var b=a.checkbox;o(["legendItem","legendLine","legendSymbol"],function(b){a[b]&&a[b].destroy()});b&&Tb(a.checkbox)}, -renderLegend:e,destroy:function(){ua&&(ua=ua.destroy());A&&(A=A.destroy())}}}};Db=function(a,b){return a>=0&&a<=ka&&b>=0&&b<=la};Fb=function(){var a=m.resetZoomButton;aa(m,"selection",{resetSelection:!0},zb);if(a)m.resetZoomButton=a.destroy()};zb=function(a){var b;m.resetZoomEnabled!==!1&&!m.resetZoomButton&&k();!a||a.resetSelection?o(xa,function(a){a.options.zoomEnabled!==!1&&(a.setExtremes(null,null,!1),b=!0)}):o(a.xAxis.concat(a.yAxis),function(a){var c=a.axis;if(m.tracker[c.isXAxis?"zoomX":"zoomY"])c.setExtremes(a.min, -a.max,!1),b=!0});b&&h(p(q.animation,m.pointCount<100))};m.pan=function(a){var b=m.xAxis[0],c=m.mouseDownX,d=b.pointRange/2,e=b.getExtremes(),f=b.translate(c-a,!0)+d,c=b.translate(c+ka-a,!0)-d;(d=m.hoverPoints)&&o(d,function(a){a.setState()});f>Ua(e.dataMin,e.min)&&c<W(e.dataMax,e.max)&&b.setExtremes(f,c,!0,!1);m.mouseDownX=a;P(D,{cursor:"move"})};Wb=function(){var a=v.legend,b=p(a.margin,10),c=a.x,d=a.y,e=a.align,f=a.verticalAlign,g;rb();if((m.title||m.subtitle)&&!s(T))(g=W(m.title&&!$.floating&& -!$.verticalAlign&&$.y||0,m.subtitle&&!ja.floating&&!ja.verticalAlign&&ja.y||0))&&(J=W(J,g+p($.margin,15)+ia));a.enabled&&!a.floating&&(e==="right"?s(w)||(ba=W(ba,Wa-c+b+ua)):e==="left"?s(bb)||(O=W(O,Wa+c+b+jb)):f==="top"?s(T)||(J=W(J,yb+d+b+ia)):f==="bottom"&&(s(E)||(M=W(M,yb-d+b+R))));m.extraBottomMargin&&(M+=m.extraBottomMargin);m.extraTopMargin&&(J+=m.extraTopMargin);Nb&&o(xa,function(a){a.getOffset()});s(bb)||(O+=pa[3]);s(T)||(J+=pa[0]);s(E)||(M+=pa[2]);s(w)||(ba+=pa[1]);sb()};tb=function(a,b, -c){var d=m.title,e=m.subtitle;La+=1;Kb(c,m);Za=ra;$a=sa;if(s(a))m.chartWidth=sa=z(a);if(s(b))m.chartHeight=ra=z(b);P(D,{width:sa+ga,height:ra+ga});I.setSize(sa,ra,c);ka=sa-O-ba;la=ra-J-M;gb=null;o(xa,function(a){a.isDirty=!0;a.setScale()});o(Q,function(a){a.isDirty=!0});m.isDirtyLegend=!0;m.isDirtyBox=!0;Wb();d&&d.align(null,null,ib);e&&e.align(null,null,ib);h(c);Za=null;aa(m,"resize");Ub===!1?t():setTimeout(t,Ub&&Ub.duration||500)};sb=function(){m.plotLeft=O=z(O);m.plotTop=J=z(J);m.plotWidth=ka= -z(sa-O-ba);m.plotHeight=la=z(ra-J-M);m.plotSizeX=U?la:ka;m.plotSizeY=U?ka:la;ib={x:jb,y:ia,width:sa-jb-ua,height:ra-ia-R};o(xa,function(a){a.setAxisSize();a.setAxisTranslation()})};rb=function(){J=p(T,ia);ba=p(w,ua);M=p(E,R);O=p(bb,jb);pa=[0,0,0,0]};qb=function(){var a=q.borderWidth||0,b=q.backgroundColor,c=q.plotBackgroundColor,d=q.plotBackgroundImage,e,f={x:O,y:J,width:ka,height:la};e=a+(q.shadow?8:0);if(a||b)ma?ma.animate(ma.crisp(null,null,null,sa-e,ra-e)):ma=I.rect(e/2,e/2,sa-e,ra-e,q.borderRadius, -a).attr({stroke:q.borderColor,"stroke-width":a,fill:b||Ma}).add().shadow(q.shadow);c&&(Na?Na.animate(f):Na=I.rect(O,J,ka,la,0).attr({fill:c}).add().shadow(q.plotShadow));d&&(Sa?Sa.animate(f):Sa=I.image(d,O,J,ka,la).add());q.plotBorderWidth&&(da?da.animate(da.crisp(null,O,J,ka,la)):da=I.rect(O,J,ka,la,0,q.plotBorderWidth).attr({stroke:q.plotBorderColor,"stroke-width":q.plotBorderWidth,zIndex:4}).add());m.isDirtyBox=!1};q.reflow!==!1&&ha(m,"load",n);if(y)for(va in y)ha(m,va,y[va]);m.options=v;m.series= -Q;m.xAxis=[];m.yAxis=[];m.addSeries=function(a,b,c){var d;a&&(Kb(c,m),b=p(b,!0),aa(m,"addSeries",{options:a},function(){d=f(a);d.isDirty=!0;m.isDirtyLegend=!0;b&&m.redraw()}));return d};m.animation=Fa?!1:p(q.animation,!0);m.Axis=c;m.destroy=function(){var a,b=D&&D.parentNode;if(m!==null){aa(m,"destroy");Qa(m);for(a=xa.length;a--;)xa[a]=xa[a].destroy();for(a=Q.length;a--;)Q[a]=Q[a].destroy();o("title,subtitle,seriesGroup,clipRect,credits,tracker,scroller,rangeSelector".split(","),function(a){var b= -m[a];b&&(m[a]=b.destroy())});o([ma,da,Na,Xa,vb,I,ub],function(a){a&&a.destroy&&a.destroy()});ma=da=Na=Xa=vb=I=ub=null;if(D)D.innerHTML="",Qa(D),b&&Tb(D),D=null;clearInterval(Bb);for(a in m)delete m[a];v=m=null}};m.get=function(a){var b,c,d;for(b=0;b<xa.length;b++)if(xa[b].options.id===a)return xa[b];for(b=0;b<Q.length;b++)if(Q[b].options.id===a)return Q[b];for(b=0;b<Q.length;b++){d=Q[b].points||[];for(c=0;c<d.length;c++)if(d[c].id===a)return d[c]}return null};m.getSelectedPoints=function(){var a= -[];o(Q,function(b){a=a.concat(nc(b.points,function(a){return a.selected}))});return a};m.getSelectedSeries=function(){return nc(Q,function(a){return a.selected})};m.hideLoading=function(){xb&&cc(xb,{opacity:0},{duration:v.loading.hideDuration||100,complete:function(){P(xb,{display:Ma})}});Ya=!1};m.initSeries=f;m.isInsidePlot=Db;m.redraw=h;m.setSize=tb;m.setTitle=j;m.showLoading=function(a){var b=v.loading;xb||(xb=Aa(Ra,{className:Ia+"loading"},L(b.style,{left:O+ga,top:J+ga,width:ka+ga,height:la+ga, -zIndex:10,display:Ma}),D),pb=Aa("span",null,b.labelStyle,xb));pb.innerHTML=a||v.lang.loading;Ya||(P(xb,{opacity:0,display:""}),cc(xb,{opacity:b.style.opacity},{duration:b.showDuration||0}),Ya=!0)};m.pointCount=0;m.counters=new tc;V()}var X,x=document,ca=window,oa=Math,z=oa.round,Ta=oa.floor,Yb=oa.ceil,W=oa.max,Ua=oa.min,Ba=oa.abs,ja=oa.cos,C=oa.sin,da=oa.PI,Dc=da*2/360,kb=navigator.userAgent,Qb=/msie/i.test(kb)&&!ca.opera,Xa=x.documentMode===8,Ec=/AppleWebKit/.test(kb),Bc=/Firefox/.test(kb),Pb=!!x.createElementNS&& -!!x.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect,Qc=Bc&&parseInt(kb.split("Firefox/")[1],10)<4,Fa=!Pb&&!Qb&&!!x.createElement("canvas").getContext,Xb,Ga=x.documentElement.ontouchstart!==X,Fc={},lc=0,tb,Ea,ac,Ub,La,E,Ra="div",wb="absolute",mc="relative",ab="hidden",Ia="highcharts-",eb="visible",ga="px",Ma="none",wa="M",fa="L",Gc="rgba(192,192,192,"+(Pb?1.0E-6:0.0020)+")",Ka="",ta="hover",Rb="millisecond",ob="second",pb="minute",va="hour",Ca="day",Ya="week",Da="month",Za="year", -sb,fc,gc,ic,db,qb,rb,pc,qc,hc,rc,sc,w=ca.HighchartsAdapter,na=w||{},Hc=na.getScript,o=na.each,nc=na.grep,Ac=na.offset,Vb=na.map,K=na.merge,ha=na.addEvent,Qa=na.removeEvent,aa=na.fireEvent,cc=na.animate,Ob=na.stop,Ha={};ca.Highcharts={};ac=function(a,b,c){if(!s(b)||isNaN(b))return"Invalid date";var a=p(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[gc](),g=d[ic](),h=d[db](),i=d[qb](),k=d[rb](),j=Ea.lang,l=j.weekdays,b={a:l[g].substr(0,3),A:l[g],d:Na(h),e:h,b:j.shortMonths[i],B:j.months[i],m:Na(i+1),y:k.toString().substr(2, -2),Y:k,H:Na(f),I:Na(f%12||12),l:f%12||12,M:Na(d[fc]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:Na(d.getSeconds()),L:Na(z(b%1E3),3)};for(e in b)a=a.replace("%"+e,b[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a};tc.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};E=za(Rb,1,ob,1E3,pb,6E4,va,36E5,Ca,864E5,Ya,6048E5,Da,2592E6,Za,31556952E3);La={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "), -c=[].concat(c),h,i,k=function(a){for(g=a.length;g--;)a[g]===wa&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(k(b),k(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));d===1&&(c=[].concat(c).splice(0,f).concat(c));a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d= -parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};w&&w.init&&w.init(La);if(!w&&ca.jQuery){var ba=jQuery,Hc=ba.getScript,o=function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c},nc=ba.grep,Vb=function(a,b){for(var c=[],d=0,e=a.length;d<e;d++)c[d]=b.call(a[d],a[d],d,a);return c},K=function(){var a=arguments;return ba.extend(!0,null,a[0],a[1],a[2],a[3])},Ac=function(a){return ba(a).offset()},ha=function(a,b,c){ba(a).bind(b,c)},Qa=function(a, -b,c){var d=x.removeEventListener?"removeEventListener":"detachEvent";x[d]&&!a[d]&&(a[d]=function(){});ba(a).unbind(b,c)},aa=function(a,b,c,d){var e=ba.Event(b),f="detached"+b,g;L(e,c);a[b]&&(a[f]=a[b],a[b]=null);o(["preventDefault","stopPropagation"],function(a){var b=e[a];e[a]=function(){try{b.call(e)}catch(c){a==="preventDefault"&&(g=!0)}}});ba(a).trigger(e);a[f]&&(a[b]=a[f],a[f]=null);d&&!e.isDefaultPrevented()&&!g&&d(e)},cc=function(a,b,c){var d=ba(a);if(b.d)a.toD=b.d,b.d=1;d.stop();d.animate(b, -c)},Ob=function(a){ba(a).stop()};ba.extend(ba.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});var Ic=jQuery.fx,Jc=Ic.step;o(["cur","_default","width","height"],function(a,b){var c=b?Jc:Ic.prototype,d=c[a],e;d&&(c[a]=function(a){a=b?a:this;e=a.elem;return e.attr?e.attr(a.prop,a.now):d.apply(this,arguments)})});Jc.d=function(a){var b=a.elem;if(!a.started){var c=La.init(b,b.d,b.toD);a.start=c[0];a.end=c[1];a.started=!0}b.attr("d",La.step(a.start,a.end,a.pos,b.toD))}}w={enabled:!0, -align:"center",x:0,y:15,style:{color:"#666",fontSize:"11px",lineHeight:"14px"}};Ea={colors:"#4572A7,#AA4643,#89A54E,#80699B,#3D96AE,#DB843D,#92A8CD,#A47D7C,#B5CA92".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","), -decimalPoint:".",resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/2.2.1/modules/canvas-tools.js"},chart:{borderColor:"#4572A7",borderRadius:5,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacingTop:10,spacingRight:10,spacingBottom:15,spacingLeft:10,style:{fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',fontSize:"12px"},backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0", -resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",y:15,style:{color:"#3E576F",fontSize:"16px"}},subtitle:{text:"",align:"center",y:30,style:{color:"#6D869F"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,shadow:!0,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:K(w, -{enabled:!1,y:-6,formatter:function(){return this.y}}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:wb,color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderWidth:1,borderColor:"#909090",borderRadius:5,shadow:!1,style:{padding:"5px"},itemStyle:{cursor:"pointer",color:"#3E576F"},itemHoverStyle:{color:"#000000"},itemHiddenStyle:{color:"#C0C0C0"}, -itemCheckboxStyle:{position:wb,width:"13px",height:"13px"},symbolWidth:16,symbolPadding:5,verticalAlign:"bottom",x:0,y:0},loading:{labelStyle:{fontWeight:"bold",position:mc,top:"1em"},style:{position:wb,backgroundColor:"white",opacity:0.5,textAlign:"center"}},tooltip:{enabled:!0,backgroundColor:"rgba(255, 255, 255, .85)",borderWidth:2,borderRadius:5,headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>', -shadow:!0,shared:Fa,snap:Ga?25:10,style:{color:"#333333",fontSize:"12px",padding:"5px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"10px"}}};var $b={dateTimeLabelFormats:za(Rb,"%H:%M:%S.%L",ob,"%H:%M:%S",pb,"%H:%M",va,"%H:%M",Ca,"%e. %b",Ya,"%e. %b",Da,"%b '%y",Za,"%Y"),endOnTick:!1,gridLineColor:"#C0C0C0",labels:w,lineColor:"#C0D0E0",lineWidth:1, -max:null,min:null,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#6D869F",fontWeight:"bold"}},type:"linear"},kc=K($b,{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{align:"right",x:-8, -y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Y-values"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:w.style}}),Pc={labels:{align:"right",x:-8,y:null},title:{rotation:270}},Oc={labels:{align:"left",x:8,y:null},title:{rotation:90}},zc={labels:{align:"center",x:0,y:14,overflow:"justify"},title:{rotation:0}},Nc=K(zc,{labels:{y:-5,overflow:"justify"}}),M=Ea.plotOptions,w=M.line;M.spline=K(w);M.scatter=K(w,{lineWidth:0,states:{hover:{lineWidth:0}}, -tooltip:{headerFormat:'<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>"}});M.area=K(w,{threshold:0});M.areaspline=K(M.area);M.column=K(w,{borderColor:"#FFFFFF",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{y:null,verticalAlign:null}, -threshold:0});M.bar=K(M.column,{dataLabels:{align:"left",x:5,y:null,verticalAlign:"middle"}});M.pie=K(w,{borderColor:"#FFFFFF",borderWidth:1,center:["50%","50%"],colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name},y:5},legendType:"point",marker:null,size:"75%",showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}}});vc();var ma=function(a){var b=[],c;(function(a){(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))? -b=[S(c[1]),S(c[2]),S(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))&&(b=[S(c[1],16),S(c[2],16),S(c[3],16),1])})(a);return{get:function(c){return b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a},brighten:function(a){if(Bb(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=S(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},setOpacity:function(a){b[3]=a;return this}}};Sa.prototype={init:function(a,b){this.element= -b==="span"?Aa(b):x.createElementNS("http://www.w3.org/2000/svg",b);this.renderer=a;this.attrSetters={}},animate:function(a,b,c){b=p(b,Ub,!0);Ob(this);if(b){b=K(b);if(c)b.complete=c;cc(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName,i=this.renderer,k,j=this.attrSetters,l=this.shadows,n,o=this;Ab(a)&&s(b)&&(c=a,a={},a[c]=b);if(Ab(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),o=A(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&& -(o=parseFloat(o));else for(c in a)if(k=!1,d=a[c],e=j[c]&&j[c](d,c),e!==!1){e!==X&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&(d="M 0 0"),this.d=d;else if(c==="x"&&h==="text"){for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],A(f,"x")===A(g,"x")&&A(f,"x",d);this.rotation&&A(g,"transform","rotate("+this.rotation+" "+d+" "+S(a.y||A(g,"y"))+")")}else if(c==="fill")d=i.color(d,g,c);else if(h==="circle"&&(c==="x"||c==="y"))c={x:"cx",y:"cy"}[c]||c;else if(h==="rect"&&c==="r")A(g, -{rx:d,ry:d}),k=!0;else if(c==="translateX"||c==="translateY"||c==="rotation"||c==="verticalAlign")this[c]=d,this.updateTransform(),k=!0;else if(c==="stroke")d=i.color(d,g,c);else if(c==="dashstyle")if(c="stroke-dasharray",d=d&&d.toLowerCase(),d==="solid")d=Ma;else{if(d){d=d.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(","); -for(e=d.length;e--;)d[e]=S(d[e])*a["stroke-width"];d=d.join(",")}}else c==="isTracker"?this[c]=d:c==="width"?d=S(d):c==="align"?(c="text-anchor",d={left:"start",center:"middle",right:"end"}[d]):c==="title"&&(e=x.createElementNS("http://www.w3.org/2000/svg","title"),e.appendChild(x.createTextNode(d)),g.appendChild(e));c==="strokeWidth"&&(c="stroke-width");Ec&&c==="stroke-width"&&d===0&&(d=1.0E-6);this.symbolName&&/^(x|y|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(n||(this.symbolAttr(a),n=!0),k= -!0);if(l&&/^(width|height|visibility|x|y|d|transform)$/.test(c))for(e=l.length;e--;)A(l[e],c,d);if((c==="width"||c==="height")&&h==="rect"&&d<0)d=0;c==="text"?(this.textStr=d,this.added&&i.buildText(this)):k||A(g,c,d)}if(Ec&&/Chrome\/(18|19)/.test(kb)&&h==="text"&&(a.x!==X||a.y!==X))c=g.parentNode,d=g.nextSibling,c&&(c.removeChild(g),d?c.insertBefore(g,d):c.appendChild(g));return o},symbolAttr:function(a){var b=this;o("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]= -p(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path","url("+this.renderer.url+"#"+a.id+")")},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;i=z(a)%2/2;h.x=Ta(b||this.x||0)+i;h.y=Ta(c||this.y||0)+i;h.width=Ta((d||this.width||0)-2*i);h.height=Ta((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b= -this.element,b=a&&a.width&&b.nodeName==="text",c,d="",e=function(a,b){return"-"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=L(this.styles,a);if(Qb&&!Pb)b&&delete a.width,P(this.element,a);else{for(c in a)d+=c.replace(/([A-Z])/g,e)+":"+a[c]+";";this.attr({style:d})}b&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){var c=b;Ga&&a==="click"&&(a="touchstart",c=function(a){a.preventDefault();b()});this.element["on"+a]=c;return this},translate:function(a,b){return this.attr({translateX:a, -translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName==="SPAN"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=L(this.styles,a);P(this.element,a);return this},htmlGetBBox:function(a){var b=this.element,c=this.bBox;if(!c||a){if(b.nodeName==="text")b.style.position=wb;c=this.bBox={x:b.offsetLeft,y:b.offsetTop,width:b.offsetWidth,height:b.offsetHeight}}return c},htmlUpdateTransform:function(){if(this.added){var a= -this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:0.5,right:1}[g],i=g&&g!=="left",k=this.shadows;if(c||d)P(b,{marginLeft:c,marginTop:d}),k&&o(k,function(a){P(a,{marginLeft:c+1,marginTop:d+1})});this.inverted&&o(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName==="SPAN"){var j,l,k=this.rotation,n;j=0;var t=1,r=0,Z;n=S(this.textWidth);var V=this.xCorr||0,v=this.yCorr||0,y=[k,g,b.innerHTML,this.textWidth].join(","); -if(y!==this.cTT)s(k)&&(j=k*Dc,t=ja(j),r=C(j),P(b,{filter:k?["progid:DXImageTransform.Microsoft.Matrix(M11=",t,", M12=",-r,", M21=",r,", M22=",t,", sizingMethod='auto expand')"].join(""):Ma})),j=p(this.elemWidth,b.offsetWidth),l=p(this.elemHeight,b.offsetHeight),j>n&&(P(b,{width:n+ga,display:"block",whiteSpace:"normal"}),j=n),n=a.fontMetrics(b.style.fontSize).b,V=t<0&&-j,v=r<0&&-l,Z=t*r<0,V+=r*n*(Z?1-h:h),v-=t*n*(k?Z?h:1-h:1),i&&(V-=j*h*(t<0?-1:1),k&&(v-=l*h*(r<0?-1:1)),P(b,{textAlign:g})),this.xCorr= -V,this.yCorr=v;P(b,{left:e+V+ga,top:f+v+ga});this.cTT=y}}else this.alignOnAdd=!0},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.inverted,d=this.rotation,e=[];c&&(a+=this.attr("width"),b+=this.attr("height"));(a||b)&&e.push("translate("+a+","+b+")");c?e.push("rotate(90) scale(-1,1)"):d&&e.push("rotate("+d+" "+this.x+" "+this.y+")");e.length&&A(this.element,"transform",e.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a, -b,c){a?(this.alignOptions=a,this.alignByTranslate=b,c||this.renderer.alignedObjects.push(this)):(a=this.alignOptions,b=this.alignByTranslate);var c=p(c,this.renderer),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),h={};/^(right|center)$/.test(d)&&(f+=(c.width-(a.width||0))/{right:1,center:2}[d]);h[b?"translateX":"x"]=z(f);/^(bottom|middle)$/.test(e)&&(g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1));h[b?"translateY":"y"]=z(g);this[this.placed?"animate":"attr"](h);this.placed= -!0;this.alignAttr=h;return this},getBBox:function(a){var b,c,d=this.rotation;c=this.element;var e=d*Dc;if(c.namespaceURI==="http://www.w3.org/2000/svg"){try{b=c.getBBox?L({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(f){}if(!b||b.width<0)b={width:0,height:0};a=b.width;c=b.height;if(d)b.width=Ba(c*C(e))+Ba(a*ja(e)),b.height=Ba(c*ja(e))+Ba(a*C(e))}else b=this.htmlGetBBox(a);return b},show:function(){return this.attr({visibility:eb})},hide:function(){return this.attr({visibility:ab})}, -add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=A(f,"zIndex"),h;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=S(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=e[c],b=A(a,"zIndex"),a!==f&&(S(b)>g||!s(g)&&s(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;aa(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element|| -{},c=a.shadows,d=a.box,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=null;Ob(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();a.stops=null}a.safeRemoveChild(b);c&&o(c,function(b){a.safeRemoveChild(b)});d&&d.destroy();Gb(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},empty:function(){for(var a=this.element,b=a.childNodes,c=b.length;c--;)a.removeChild(b[c])},shadow:function(a,b){var c=[],d,e,f=this.element, -g=this.parentInverted?"(-1,-1)":"(1,1)";if(a){for(d=1;d<=3;d++)e=f.cloneNode(0),A(e,{isShadow:"true",stroke:"rgb(0, 0, 0)","stroke-opacity":0.05*d,"stroke-width":7-2*d,transform:"translate"+g,fill:Ma}),b?b.element.appendChild(e):f.parentNode.insertBefore(e,f),c.push(e);this.shadows=c}return this}};var Eb=function(){this.init.apply(this,arguments)};Eb.prototype={Element:Sa,init:function(a,b,c,d){var e=location,f;f=this.createElement("svg").attr({xmlns:"http://www.w3.org/2000/svg",version:"1.1"});a.appendChild(f.element); -this.isSVG=!0;this.box=f.element;this.boxWrapper=f;this.alignedObjects=[];this.url=Qb?"":e.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1");this.defs=this.createElement("defs").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1)},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Jb(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a); -return b},draw:function(){},buildText:function(a){for(var b=a.element,c=p(a.textStr,"").toString().replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g),d=b.childNodes,e=/style="([^"]+)"/,f=/href="([^"]+)"/,g=A(b,"x"),h=a.styles,i=h&&S(h.width),k=h&&h.lineHeight,j,h=d.length;h--;)b.removeChild(d[h]);i&&!a.added&&this.box.appendChild(b);c[c.length-1]===""&& -c.pop();o(c,function(c,d){var h,r=0,p,c=c.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");h=c.split("|||");o(h,function(c){if(c!==""||h.length===1){var l={},o=x.createElementNS("http://www.w3.org/2000/svg","tspan");e.test(c)&&A(o,"style",c.match(e)[1].replace(/(;| |^)color([ :])/,"$1fill$2"));f.test(c)&&(A(o,"onclick",'location.href="'+c.match(f)[1]+'"'),P(o,{cursor:"pointer"}));c=(c.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"<").replace(/>/g,">");o.appendChild(x.createTextNode(c)); -r?l.dx=3:l.x=g;if(!r){if(d){!Pb&&a.renderer.forExport&&P(o,{display:"block"});p=ca.getComputedStyle&&S(ca.getComputedStyle(j,null).getPropertyValue("line-height"));if(!p||isNaN(p))p=k||j.offsetHeight||18;A(o,"dy",p)}j=o}A(o,l);b.appendChild(o);r++;if(i)for(var c=c.replace(/-/g,"- ").split(" "),q,T=[];c.length||T.length;)q=a.getBBox().width,l=q>i,!l||c.length===1?(c=T,T=[],c.length&&(o=x.createElementNS("http://www.w3.org/2000/svg","tspan"),A(o,{dy:k||16,x:g}),b.appendChild(o),q>i&&(i=q))):(o.removeChild(o.firstChild), -T.unshift(c.pop())),c.length&&o.appendChild(x.createTextNode(c.join(" ").replace(/- /g,"-")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c),i=0,k,j,l,n,o,a={x1:0,y1:0,x2:0,y2:1},e=K(za("stroke-width",1,"stroke","#999","fill",za("linearGradient",a,"stops",[[0,"#FFF"],[1,"#DDD"]]),"r",3,"padding",3,"style",za("color","black")),e);l=e.style;delete e.style;f=K(e,za("stroke","#68A","fill",za("linearGradient",a,"stops",[[0,"#FFF"],[1,"#ACF"]])),f);n=f.style;delete f.style;g=K(e,za("stroke", -"#68A","fill",za("linearGradient",a,"stops",[[0,"#9BD"],[1,"#CDF"]])),g);o=g.style;delete g.style;ha(h.element,"mouseenter",function(){h.attr(f).css(n)});ha(h.element,"mouseleave",function(){k=[e,f,g][i];j=[l,n,o][i];h.attr(k).css(j)});h.setState=function(a){(i=a)?a===2&&h.attr(g).css(o):h.attr(e).css(l)};return h.on("click",function(){d.call(h)}).attr(e).css(L({cursor:"default"},l))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=z(a[1])+b%2/2);a[2]===a[5]&&(a[2]=a[5]=z(a[2])+b%2/2);return a},path:function(a){return this.createElement("path").attr({d:a, -fill:Ma})},circle:function(a,b,c){a=mb(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;return this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.width,d=a.height,e=a.r,f=a.strokeWidth,a=a.x;e=this.createElement("rect").attr({rx:e,ry:e,fill:Ma});return e.attr(e.crisp(f,a,b,W(c,0),W(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects, -e=d.length;this.width=a;this.height=b;for(this.boxWrapper[p(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return s(a)?b.attr({"class":Ia+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Ma};arguments.length>1&&L(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a, -b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(z(b),z(c),d,e,f),i=/^url\((.*?)\)$/,k;if(h)g=this.path(h),L(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&L(g,f);else if(i.test(a)){var j=function(a,b){a.attr({width:b[0],height:b[1]}).translate(-z(b[0]/2),-z(b[1]/2))};k=a.match(i)[1];a=Fc[k];g=this.image(k).attr({x:b,y:c});a?j(g,a):(g.attr({width:0,height:0}),Aa("img",{onload:function(){j(g,Fc[k]=[this.width,this.height])},src:k}))}return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return[wa,a+c/2, -b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return[wa,a,b,fa,a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return[wa,a+c/2,b,fa,a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return[wa,a,b,fa,a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return[wa,a+c/2,b,fa,a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-1.0E-6,d=e.innerR,h=ja(f),i=C(f),k=ja(g),g=C(g),e=e.end-f<da?0:1;return[wa,a+c*h,b+c*i, -"A",c,c,0,e,1,a+c*k,b+c*g,fa,a+d*k,b+d*g,"A",d,d,0,e,0,a+d*h,b+d*i,"Z"]}},clipRect:function(a,b,c,d){var e=Ia+lc++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d,e=/^rgba/;if(a&&a.linearGradient){var f=this,g=a.linearGradient,b=!Fb(g),c=f.gradients,h,i=g.x1||g[0]||0,k=g.y1||g[1]||0,j=g.x2||g[2]||0,l=g.y2||g[3]||0,n,t,r=[b,i,k,j,l,a.stops.join(",")].join(",");c[r]?g=A(c[r].element,"id"):(g=Ia+lc++, -h=f.createElement("linearGradient").attr(L({id:g,x1:i,y1:k,x2:j,y2:l},b?null:{gradientUnits:"userSpaceOnUse"})).add(f.defs),h.stops=[],o(a.stops,function(a){e.test(a[1])?(d=ma(a[1]),n=d.get("rgb"),t=d.get("a")):(n=a[1],t=1);a=f.createElement("stop").attr({offset:a[0],"stop-color":n,"stop-opacity":t}).add(h);h.stops.push(a)}),c[r]=h);return"url("+this.url+"#"+g+")"}else return e.test(a)?(d=ma(a),A(b,c+"-opacity",d.get("a")),d.get("rgb")):(b.removeAttribute(c+"-opacity"),a)},text:function(a,b,c,d){var e= -Ea.chart.style;if(d&&!this.forExport)return this.html(a,b,c);b=z(p(b,0));c=z(p(c,0));a=this.createElement("text").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,fontSize:e.fontSize});a.x=b;a.y=c;return a},html:function(a,b,c){var d=Ea.chart.style,e=this.createElement("span"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b==="align"&&(b="textAlign");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:z(b),y:z(c)}).css({position:wb, -whiteSpace:"nowrap",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;if(h.isSVG)e.add=function(a){var b,c,d=h.box.parentNode;if(a){if(b=a.div,!b)b=a.div=Aa(Ra,{className:A(a.element,"class")},{position:wb,left:a.attr("translateX")+ga,top:a.attr("translateY")+ga},d),c=b.style,L(a.attrSetters,{translateX:function(a){c.left=a+ga},translateY:function(a){c.top=a+ga},visibility:function(a,b){c[b]=a}})}else b=d;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};return e}, -fontMetrics:function(a){var a=S(a||11),a=a<24?a+4:z(a*1.2),b=z(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h){function i(){var a=n.styles,a=a&&a.textAlign,b=v,c;c=h?0:ia;if(s(y)&&(a==="center"||a==="right"))b+={center:0.5,right:1}[a]*(y-p.width);(b!==t.x||c!==t.y)&&t.attr({x:b,y:c});t.x=b;t.y=c}function k(a,b){r?r.attr(a,b):x[a]=b}function j(){n.attr({text:a,x:b,y:c,anchorX:e,anchorY:f})}var l=this,n=l.g(),t=l.text("",0,0,g).attr({zIndex:1}).add(n),r,p,V="left",v=3,y,q,T,A,w=0,x={},ia,g= -n.attrSetters;ha(n,"add",j);g.width=function(a){y=a;return!1};g.height=function(a){q=a;return!1};g.padding=function(a){s(a)&&a!==v&&(v=a,i());return!1};g.align=function(a){V=a;return!1};g.text=function(a,b){t.attr(b,a);var c;c=t.element.style;p=(y===void 0||q===void 0||n.styles.textAlign)&&t.getBBox(!0);n.width=(y||p.width)+2*v;n.height=(q||p.height)+2*v;ia=v+l.fontMetrics(c&&c.fontSize).b;if(!r)c=h?-ia:0,n.box=r=d?l.symbol(d,0,c,n.width,n.height):l.rect(0,c,n.width,n.height,0,x["stroke-width"]), -r.add(n);r.attr(K({width:n.width,height:n.height},x));x=null;i();return!1};g["stroke-width"]=function(a,b){w=a%2/2;k(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){k(b,a);return!1};g.anchorX=function(a,b){e=a;k(b,a+w-T);return!1};g.anchorY=function(a,b){f=a;k(b,a-A);return!1};g.x=function(a){a-={left:0,center:0.5,right:1}[V]*((y||p.width)+v);T=n.x=z(a);n.attr("translateX",T);return!1};g.y=function(a){A=n.y=z(a);n.attr("translateY",a);return!1};var ua=n.css;return L(n,{css:function(a){if(a){var b= -{},a=K({},a);o("fontSize,fontWeight,fontFamily,color,lineHeight,width".split(","),function(c){a[c]!==X&&(b[c]=a[c],delete a[c])});t.css(b)}return ua.call(n,a)},getBBox:function(){return r.getBBox()},shadow:function(a){r.shadow(a);return n},destroy:function(){Qa(n,"add",j);Qa(n.element,"mouseenter");Qa(n.element,"mouseleave");t&&(t=t.destroy());Sa.prototype.destroy.call(n)}})}};Xb=Eb;var $a;if(!Pb&&!Fa)$a={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ",wb,";"];(b==="shape"|| -b===Ra)&&d.push("left:0;top:0;width:10px;height:10px;");Xa&&d.push("visibility: ",b===Ra?ab:eb);c.push(' style="',d.join(""),'"/>');if(b)c=b===Ra||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=Aa(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);Xa&&d.gVis===ab&&P(c,{visibility:ab});d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();aa(this, -"add");return this},toggleChildren:function(a,b){for(var c=a.childNodes,d=c.length;d--;)P(c[d],{visibility:b}),c[d].nodeName==="DIV"&&this.toggleChildren(c[d],b)},updateTransform:Sa.prototype.htmlUpdateTransform,attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,k=this.symbolName,j,l=this.shadows,n,o=this.attrSetters,r=this;Ab(a)&&s(b)&&(c=a,a={},a[c]=b);if(Ab(a))c=a,r=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],n=!1, -e=o[c]&&o[c](d,c),e!==!1&&d!==null){e!==X&&(d=e);if(k&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))j||(this.symbolAttr(a),j=!0),n=!0;else if(c==="d"){d=d||[];this.d=d.join(" ");e=d.length;for(n=[];e--;)n[e]=Bb(d[e])?z(d[e]*10)-5:d[e]==="Z"?"x":d[e];d=n.join(" ")||"x";f.path=d;if(l)for(e=l.length;e--;)l[e].path=d;n=!0}else if(c==="zIndex"||c==="visibility"){if(Xa&&c==="visibility"&&h==="DIV")f.gVis=d,this.toggleChildren(f,d),d===eb&&(d=null);d&&(g[c]=d);n=!0}else if(c==="width"|| -c==="height")d=W(0,d),this[c]=d,this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,n=!0;else if(c==="x"||c==="y")this[c]=d,g[{x:"left",y:"top"}[c]]=d;else if(c==="class")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,Bb(d)&&(d+=ga);else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||Aa(i.prepVML(["<stroke/>"]),null,null,f))[c]=d||"solid",this.dashstyle=d,n=!0;else if(c=== -"fill")h==="SPAN"?g.color=d:(f.filled=d!==Ma?!0:!1,d=i.color(d,f,c),c="fillcolor");else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),n=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,n=!0;if(l&&c==="visibility")for(e=l.length;e--;)l[e].style[c]=d;n||(Xa?f[c]=d:A(f,c,d))}return r},clip:function(a){var b=this,c=a.members;c.push(b);b.destroyClip=function(){Gb(c,b)};return b.css(a.getCSS(b.inverted))},css:Sa.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&& -Tb(a)},destroy:function(){this.destroyClip&&this.destroyClip();return Sa.prototype.destroy.apply(this)},empty:function(){for(var a=this.element.childNodes,b=a.length,c;b--;)c=a[b],c.parentNode.removeChild(c)},on:function(a,b){this.element["on"+a]=function(){var a=ca.event;a.target=a.srcElement;b(a)};return this},shadow:function(a,b){var c=[],d,e=this.element,f=this.renderer,g,h=e.style,i,k=e.path;k&&typeof k.value!=="string"&&(k="x");if(a){for(d=1;d<=3;d++)i=['<shape isShadow="true" strokeweight="', -7-2*d,'" filled="false" path="',k,'" coordsize="100,100" style="',e.style.cssText,'" />'],g=Aa(f.prepVML(i),null,{left:S(h.left)+1,top:S(h.top)+1}),i=['<stroke color="black" opacity="',0.05*d,'"/>'],Aa(f.prepVML(i),null,null,g),b?b.element.appendChild(g):e.parentNode.insertBefore(g,e),c.push(g);this.shadows=c}return this}},$a=pa(Sa,$a),w={Element:$a,isIE8:kb.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(Ra);e=d.element;e.style.position=mc;a.appendChild(d.element); -this.box=e;this.boxWrapper=d;this.setSize(b,c,!1);if(!x.namespaces.hcv)x.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),x.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "},clipRect:function(a,b,c,d){var e=this.createElement();return L(e,{members:[],left:a,top:b,width:c,height:d,getCSS:function(a){var b=this.top,c=this.left,d=c+this.width,e=b+this.height,b={clip:"rect("+z(a?c:b)+"px,"+z(a?e:d)+"px,"+z(a?d:e)+ -"px,"+z(a?b:c)+"px)"};!a&&Xa&&L(b,{width:d+ga,height:e+ga});return b},updateClipping:function(){o(e.members,function(a){a.css(e.getCSS(a.inverted))})}})},color:function(a,b,c){var d,e=/^rgba/;if(a&&a.linearGradient){var f,g,h=a.linearGradient,i=h.x1||h[0]||0,k=h.y1||h[1]||0,j=h.x2||h[2]||0,h=h.y2||h[3]||0,l,n,p,r;o(a.stops,function(a,b){e.test(a[1])?(d=ma(a[1]),f=d.get("rgb"),g=d.get("a")):(f=a[1],g=1);b?(p=f,r=g):(l=f,n=g)});if(c==="fill")a=90-oa.atan((h-k)/(j-i))*180/da,a=['<fill colors="0% ',l, -",100% ",p,'" angle="',a,'" opacity="',r,'" o:opacity2="',n,'" type="gradient" focus="100%" method="sigma" />'],Aa(this.prepVML(a),null,null,b);else return f}else if(e.test(a)&&b.tagName!=="IMG")return d=ma(a),a=["<",c,' opacity="',d.get("a"),'"/>'],Aa(this.prepVML(a),null,null,b),d.get("rgb");else{b=b.getElementsByTagName(c);if(b.length)b[0].opacity=1;return a}},prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')=== --1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:");return a},text:Eb.prototype.html,path:function(a){return this.createElement("shape").attr({coordsize:"100 100",d:a})},circle:function(a,b,c){return this.symbol("circle").attr({x:a-c,y:b-c,width:2*c,height:2*c})},g:function(a){var b;a&&(b={className:Ia+a,"class":Ia+a});return this.createElement(Ra).attr(b)},image:function(a, -b,c,d,e){var f=this.createElement("img").attr({src:a});arguments.length>1&&f.css({left:b,top:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol("rect");g.r=e;return g.attr(g.crisp(f,a,b,W(c,0),W(d,0)))},invertChild:function(a,b){var c=b.style;P(a,{flip:"x",left:S(c.width)-10,top:S(c.height)-10,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,c=e.r||c||d,d=ja(f),h=C(f),i=ja(g),k=C(g),e=e.innerR, -j=0.08/c,l=e&&0.25/e||0;if(g-f===0)return["x"];else 2*da-g+f<j?i=-j:g-f<l&&(i=ja(f+l));return["wa",a-c,b-c,a+c,b+c,a+c*d,b+c*h,a+c*i,b+c*k,"at",a-e,b-e,a+e,b+e,a+e*i,b+e*k,a+e*d,b+e*h,"x","e"]},circle:function(a,b,c,d){return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){if(!s(e))return[];var f=a+c,g=b+d,c=Ua(e.r||0,c,d);return[wa,a+c,b,fa,f-c,b,"wa",f-2*c,b,f,b+2*c,f-c,b,f,b+c,fa,f,g-c,"wa",f-2*c,g-2*c,f,g,f,g-c,f-c,g,fa,a+c,g,"wa",a,g-2*c,a+2*c,g,a+c,g,a,g-c,fa,a,b+c,"wa", -a,b,a+2*c,b+2*c,a,b+c,a+c,b,"x","e"]}}},$a=function(){this.init.apply(this,arguments)},$a.prototype=K(Eb.prototype,w),Xb=$a;var oc,Cc;Fa&&(oc=function(){},Cc=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Hc(d,a);b.push(c)}}}());Xb=$a||oc||Eb;wc.prototype.callbacks=[];var lb=function(){};lb.prototype={init:function(a,b,c){var d=a.chart.counters;this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint){b= -a.chart.options.colors;if(!this.options)this.options={};this.color=this.options.color=this.color||b[d.color++];d.wrapColor(b.length)}a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=typeof a;this.config=a;if(d==="number"||a===null)this.y=a;else if(typeof a[0]==="number")this.x=a[0],this.y=a[1];else if(d==="object"&&typeof a.length!=="number"){if(L(this,a),this.options=a,a.dataLabels)c._hasPointLabels=!0}else if(typeof a[0]==="string")this.name=a[0],this.y=a[1];if(this.x=== -X)this.x=b===X?c.autoIncrement():b},destroy:function(){var a=this.series,b=a.chart.hoverPoints,c;a.chart.pointCount--;b&&(this.setState(),Gb(b,this));if(this===a.chart.hoverPoint)this.onMouseOut();a.chart.hoverPoints=null;if(this.graphic||this.dataLabel)Qa(this),this.destroyElements();this.legendItem&&this.series.chart.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a="graphic,tracker,dataLabel,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&& -(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series.chart,a=p(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=a;c.setState(a&&"select");b||o(d.getSelectedPoints(),function(a){if(a.selected&&a!==c)a.selected=!1,a.setState(Ka),a.firePointEvent("unselect")})})}, -onMouseOver:function(){var a=this.series,b=a.chart,c=b.tooltip,d=b.hoverPoint;if(d&&d!==this)d.onMouseOut();this.firePointEvent("mouseOver");c&&(!c.shared||a.noSharedTooltip)&&c.refresh(this);this.setState(ta);b.hoverPoint=this},onMouseOut:function(){this.firePointEvent("mouseOut");this.setState();this.series.chart.hoverPoint=null},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=String(this.y).split("."),d=d[1]?d[1].length:0,e=a.match(/\{(series|point)\.[a-zA-Z]+\}/g),f=/[{\.}]/, -g,h,i,k;for(k in e)h=e[k],Ab(h)&&h!==a&&(i=(" "+h).split(f),g={point:this,series:b}[i[1]],i=i[2],g=g===this&&(i==="y"||i==="open"||i==="high"||i==="low"||i==="close")?(c.valuePrefix||c.yPrefix||"")+dc(this[i],p(c.valueDecimals,c.yDecimals,d))+(c.valueSuffix||c.ySuffix||""):g[i],a=a.replace(h,g));return a},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=h.length,k=e.chart,b=p(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);mb(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state])); -for(g=0;g<i;g++)if(h[g]===d){e.xData[g]=d.x;e.yData[g]=d.y;e.options.data[g]=a;break}e.isDirty=!0;e.isDirtyData=!0;b&&k.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.chart,f,g=d.data,h=g.length;Kb(b,e);a=p(a,!0);c.firePointEvent("remove",null,function(){for(f=0;f<h;f++)if(g[f]===c){g.splice(f,1);d.options.data.splice(f,1);d.xData.splice(f,1);d.yData.splice(f,1);break}c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&e.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options; -(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a==="click"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});aa(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=K(this.series.options.point,this.options).events,b;this.events=a;for(b in a)ha(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=M[d.type].marker&&d.options.marker, -g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,k=d.stateMarkerGraphic,j=d.chart,l=this.pointAttr,a=a||Ka;if(!(a===this.state||this.selected&&a!=="select"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&l[a].r,this.graphic.attr(K(l[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a){if(!k)e=f.radius,d.stateMarkerGraphic=k=j.renderer.symbol(d.symbol,-e,-e,2*e,2*e).attr(l[a]).add(d.group);k.translate(b,c)}if(k)k[a?"show":"hide"]()}this.state= -a}}};var $=function(){};$.prototype={isCartesian:!0,type:"line",pointClass:lb,sorted:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},init:function(a,b){var c,d;d=a.series.length;this.chart=a;this.options=b=this.setOptions(b);this.bindAxes();L(this,{index:d,name:b.name||"Series "+(d+1),state:Ka,pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if(Fa)b.animation=!1;d=b.events;for(c in d)ha(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&& -b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1)},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&o(["xAxis","yAxis"],function(e){o(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]===X&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0})})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=p(b,a.pointStart,0);this.pointInterval=p(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval; -return b},getSegments:function(){var a=-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else o(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=a.data;a.data=null;c=K(c[this.type],c.series,a);c.data=a.data=d;this.tooltipOptions=K(b.tooltip,c.tooltip);return c},getColor:function(){var a= -this.chart.options.colors,b=this.chart.counters;this.color=this.options.color||a[b.color++]||"#0000ff";b.wrapColor(a.length)},getSymbol:function(){var a=this.options.marker,b=this.chart,c=b.options.symbols,b=b.counters;this.symbol=a.symbol||c[b.symbol++];if(/^url/.test(this.symbol))a.radius=0;b.wrapSymbol(c.length)},addPoint:function(a,b,c,d){var e=this.data,f=this.graph,g=this.area,h=this.chart,i=this.xData,k=this.yData,j=f&&f.shift||0,l=this.options.data;Kb(d,h);if(f&&c)f.shift=j+1;if(g){if(c)g.shift= -j+1;g.isArea=!0}b=p(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);i.push(d.x);k.push(this.valueCount===4?[d.open,d.high,d.low,d.close]:d.y);l.push(a);c&&(e[0]?e[0].remove(!1):(e.shift(),i.shift(),k.shift(),l.shift()));this.getAttribs();this.isDirtyData=this.isDirty=!0;b&&h.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.initialColor,f=this.chart,g=null;this.xIncrement=null;this.pointRange=this.xAxis&&this.xAxis.categories&&1||d.pointRange;if(s(e))f.counters.color= -e;var h=[],i=[],k=a?a.length:[],j=this.valueCount===4;if(k>(d.turboThreshold||1E3)){for(e=0;g===null&&e<k;)g=a[e],e++;if(Bb(g)){g=p(d.pointStart,0);d=p(d.pointInterval,1);for(e=0;e<k;e++)h[e]=g,i[e]=a[e],g+=d;this.xIncrement=g}else if(Fb(g))if(j)for(e=0;e<k;e++)d=a[e],h[e]=d[0],i[e]=d.slice(1,5);else for(e=0;e<k;e++)d=a[e],h[e]=d[0],i[e]=d[1]}else for(e=0;e<k;e++)d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[e]]),h[e]=d.x,i[e]=j?[d.open,d.high,d.low,d.close]:d.y;this.data=[];this.options.data= -a;this.xData=h;this.yData=i;for(e=c&&c.length||0;e--;)c[e]&&c[e].destroy&&c[e].destroy();this.isDirty=this.isDirtyData=f.isDirtyBox=!0;p(b,!0)&&f.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=p(a,!0);if(!c.isRemoving)c.isRemoving=!0,aa(c,"remove",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e=0,f=d,g,h,i=this.xAxis,k=this.options,j=k.cropThreshold,l=this.isCartesian;if(l&&!this.isDirty&& -!i.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(l&&this.sorted&&(!j||d>j||this.forceCrop))if(a=i.getExtremes(),i=a.min,j=a.max,b[d-1]<i||b[0]>j)b=[],c=[];else if(b[0]<i||b[d-1]>j){for(a=0;a<d;a++)if(b[a]>=i){e=W(0,a-1);break}for(;a<d;a++)if(b[a]>j){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===X||d<h))h=d;this.cropped=g;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(k.pointRange===null)this.pointRange=h||1;this.closestPointRange= -h},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,k=this.hasGroupedData,j,l=[],n;if(!b&&!k)b=[],b.length=a.length,b=this.data=b;for(n=0;n<g;n++)i=h+n,k?l[n]=(new f).init(this,[d[n]].concat(Hb(e[n]))):(b[i]?j=b[i]:b[i]=j=(new f).init(this,a[i],d[n]),l[n]=j);if(b&&(g!==(c=b.length)||k))for(n=0;n<c;n++)n===h&&!k&&(n+=g),b[n]&&b[n].destroyElements();this.data=b;this.points=l},translate:function(){this.processedXData|| -this.processData();this.generatePoints();for(var a=this.chart,b=this.options,c=b.stacking,d=this.xAxis,e=d.categories,f=this.yAxis,g=this.points,h=g.length,i=!!this.modifyValue,k,j=f.series,l=j.length;l--;)if(j[l].visible){l===this.index&&(k=!0);break}for(l=0;l<h;l++){var j=g[l],n=j.x,o=j.y,r=j.low,p=f.stacks[(o<b.threshold?"-":"")+this.stackKey];j.plotX=z(d.translate(n,0,0,0,1)*10)/10;if(c&&this.visible&&p&&p[n]){r=p[n];n=r.total;r.cum=r=r.cum-o;o=r+o;if(k)r=b.threshold;c==="percent"&&(r=n?r*100/ -n:0,o=n?o*100/n:0);j.percentage=n?j.y*100/n:0;j.stackTotal=n;j.stackY=o}j.yBottom=s(r)?f.translate(r,0,1,0,1):null;i&&(o=this.modifyValue(o,j));j.plotY=typeof o==="number"?z(f.translate(o,0,1,0,1)*10)/10:X;j.clientX=a.inverted?a.plotHeight-j.plotX:j.plotX;j.category=e&&e[j.x]!==X?e[j.x]:j.x}this.getSegments()},setTooltipPoints:function(a){var b=this.chart,c=b.inverted,d=[],b=z((c?b.plotTop:b.plotLeft)+b.plotSizeX),e,f;e=this.xAxis;var g,h,i=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints= -null;o(this.segments||this.points,function(a){d=d.concat(a)});e&&e.reversed&&(d=d.reverse());a=d.length;for(h=0;h<a;h++){g=d[h];e=d[h-1]?d[h-1]._high+1:0;for(f=g._high=d[h+1]?Ta((g.plotX+(d[h+1]?d[h+1].plotX:b))/2):b;e<=f;)i[c?b-e++:e++]=g}this.tooltipPoints=i}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat||"%A, %b %e, %Y",d=this.xAxis;return b.headerFormat.replace("{point.key}",d&&d.options.type==="datetime"?ac(c,a):a).replace("{series.name}",this.name).replace("{series.color}", -this.color)},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(Ga||!a.mouseIsDown){if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&aa(this,"mouseOver");this.setState(ta);a.hoverSeries=this}},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&aa(this,"mouseOut");c&&!a.stickyTracking&&!c.shared&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this.chart,c=this.clipRect,d=this.options.animation; -d&&!mb(d)&&(d={});if(a){if(!c.isAnimating)c.attr("width",0),c.isAnimating=!0}else c.animate({width:b.plotSizeX},d),this.animate=null},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,k,j;if(this.options.marker.enabled)for(f=b.length;f--;)if(g=b[f],d=g.plotX,e=g.plotY,j=g.graphic,e!==X&&!isNaN(e))if(a=g.pointAttr[g.selected?"select":Ka],h=a.r,i=p(g.marker&&g.marker.symbol,this.symbol),k=i.indexOf("url")===0,j)j.animate(L({x:d-h,y:e-h},j.symbolName?{width:2*h,height:2*h}:{}));else if(h> -0||k)g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(this.group)},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=p(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=M[a.type].marker?a.options.marker:a.options,c=b.states,d=c[ta],e,f=a.color,g={stroke:f,fill:f},h=a.points,i=[],k,j=a.pointAttrToOptions,l;a.options.marker?(d.radius=d.radius||b.radius+2,d.lineWidth=d.lineWidth||b.lineWidth+1):d.color= -d.color||ma(d.color||f).brighten(d.brightness).get();i[Ka]=a.convertAttribs(b,g);o([ta,"select"],function(b){i[b]=a.convertAttribs(c[b],i[Ka])});a.pointAttr=i;for(f=h.length;f--;){g=h[f];if((b=g.options&&g.options.marker||g.options)&&b.enabled===!1)b.radius=0;e=!1;if(g.options)for(l in j)s(b[j[l]])&&(e=!0);if(e){k=[];c=b.states||{};e=c[ta]=c[ta]||{};if(!a.options.marker)e.color=ma(e.color||g.options.color).brighten(e.brightness||d.brightness).get();k[Ka]=a.convertAttribs(b,i[Ka]);k[ta]=a.convertAttribs(c[ta], -i[ta],k[Ka]);k.select=a.convertAttribs(c.select,i.select,k[Ka])}else k=i;g.pointAttr=k}},destroy:function(){var a=this,b=a.chart,c=a.clipRect,d=/AppleWebKit\/533/.test(kb),e,f,g=a.data||[],h,i,k;aa(a,"destroy");Qa(a);o(["xAxis","yAxis"],function(b){if(k=a[b])Gb(k.series,a),k.isDirty=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(f=g.length;f--;)(h=g[f])&&h.destroy&&h.destroy();a.points=null;if(c&&c!==b.clipRect)a.clipRect=c.destroy();o(["area","graph","dataLabelsGroup","group","tracker"],function(b){a[b]&& -(e=d&&b==="group"?"hide":"destroy",a[b][e]())});if(b.hoverSeries===a)b.hoverSeries=null;Gb(b.series,a);for(i in a)delete a[i]},drawDataLabels:function(){var a=this,b=a.options,c=b.dataLabels;if(c.enabled||a._hasPointLabels){var d,e,f=a.points,g,h,i,k=a.dataLabelsGroup,j=a.chart,l=a.xAxis,l=l?l.left:j.plotLeft,n=a.yAxis,n=n?n.top:j.plotTop,t=j.renderer,r=j.inverted,Z=a.type,V=b.stacking,v=Z==="column"||Z==="bar",y=c.verticalAlign===null,q=c.y===null,T=t.fontMetrics(c.style.fontSize),A=T.h,x=T.b,w, -ia;v&&(T={top:x,middle:x-A/2,bottom:-A+x},V?(y&&(c=K(c,{verticalAlign:"middle"})),q&&(c=K(c,{y:T[c.verticalAlign]}))):y?c=K(c,{verticalAlign:"top"}):q&&(c=K(c,{y:T[c.verticalAlign]})));k?k.translate(l,n):k=a.dataLabelsGroup=t.g("data-labels").attr({visibility:a.visible?eb:ab,zIndex:6}).translate(l,n).add();h=c;o(f,function(f){w=f.dataLabel;c=h;(g=f.options)&&g.dataLabels&&(c=K(c,g.dataLabels));if(ia=c.enabled){var l=f.barX&&f.barX+f.barW/2||p(f.plotX,-999),n=p(f.plotY,-999),o=c.y===null?f.y>=b.threshold? --A+x:x:c.y;d=(r?j.plotWidth-n:l)+c.x;e=z((r?j.plotHeight-l:n)+o)}if(w&&a.isCartesian&&(!j.isInsidePlot(d,e)||!ia))f.dataLabel=w.destroy();else if(ia){l=c.align;i=c.formatter.call(f.getLabelConfig(),c);Z==="column"&&(d+={left:-1,right:1}[l]*f.barW/2||0);!V&&r&&f.y<0&&(l="right",d-=10);c.style.color=p(c.color,c.style.color,a.color,"black");if(w)w.attr({text:i}).animate({x:d,y:e});else if(s(i))w=f.dataLabel=t[c.rotation?"text":"label"](i,d,e,null,null,null,c.useHTML,!0).attr({align:l,fill:c.backgroundColor, -stroke:c.borderColor,"stroke-width":c.borderWidth,r:c.borderRadius,rotation:c.rotation,padding:c.padding,zIndex:1}).css(c.style).add(k).shadow(c.shadow);if(v&&b.stacking&&w)l=f.barX,n=f.barY,o=f.barW,f=f.barH,w.align(c,null,{x:r?j.plotWidth-n-f:l,y:r?j.plotHeight-l-o:n,width:r?f:o,height:r?o:f})}})}},drawGraph:function(){var a=this,b=a.options,c=a.graph,d=[],e,f=a.area,g=a.group,h=b.lineColor||a.color,i=b.lineWidth,k=b.dashStyle,j,l=a.chart.renderer,n=a.yAxis.getThreshold(b.threshold),t=/^area/.test(a.type), -r=[],s=[];o(a.segments,function(c){j=[];o(c,function(d,e){a.getPointSpline?j.push.apply(j,a.getPointSpline(c,d,e)):(j.push(e?fa:wa),e&&b.step&&j.push(d.plotX,c[e-1].plotY),j.push(d.plotX,d.plotY))});c.length>1?d=d.concat(j):r.push(c[0]);if(t){var e=[],f,g=j.length;for(f=0;f<g;f++)e.push(j[f]);g===3&&e.push(fa,j[1],j[2]);if(b.stacking&&a.type!=="areaspline")for(f=c.length-1;f>=0;f--)f<c.length-1&&b.step&&e.push(c[f+1].plotX,c[f].yBottom),e.push(c[f].plotX,c[f].yBottom);else e.push(fa,c[c.length-1].plotX, -n,fa,c[0].plotX,n);s=s.concat(e)}});a.graphPath=d;a.singlePoints=r;if(t)e=p(b.fillColor,ma(a.color).setOpacity(b.fillOpacity||0.75).get()),f?f.animate({d:s}):a.area=a.chart.renderer.path(s).attr({fill:e}).add(g);if(c)Ob(c),c.animate({d:d});else if(i){c={stroke:h,"stroke-width":i};if(k)c.dashstyle=k;a.graph=l.path(d).attr(c).add(g).shadow(b.shadow)}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};c.attr(a).invert();d&&d.attr(a).invert()}var b=this,c=b.group,d=b.trackerGroup, -e=b.chart;ha(e,"resize",a);ha(b,"destroy",function(){Qa(e,"resize",a)});a();b.invertGroups=a},render:function(){var a=this,b=a.chart,c,d=a.options,e=d.clip!==!1,f=d.animation,g=f&&a.animate,f=g?f&&f.duration||500:0,h=a.clipRect,i=b.renderer;if(!h&&(h=a.clipRect=!b.hasRendered&&b.clipRect?b.clipRect:i.clipRect(0,0,b.plotSizeX,b.plotSizeY+1),!b.clipRect))b.clipRect=h;if(!a.group)c=a.group=i.g("series"),c.attr({visibility:a.visible?eb:ab,zIndex:d.zIndex}).translate(a.xAxis.left,a.yAxis.top).add(b.seriesGroup); -a.drawDataLabels();g&&a.animate(!0);a.getAttribs();a.drawGraph&&a.drawGraph();a.drawPoints();a.options.enableMouseTracking!==!1&&a.drawTracker();b.inverted&&a.invertGroups();e&&!a.hasRendered&&(c.clip(h),a.trackerGroup&&a.trackerGroup.clip(b.clipRect));g&&a.animate();setTimeout(function(){h.isAnimating=!1;if((c=a.group)&&h!==b.clipRect&&h.renderer){if(e)c.clip(a.clipRect=b.clipRect);h.destroy()}},f);a.isDirty=a.isDirtyData=!1;a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData, -c=this.group;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:this.xAxis.left,translateY:this.yAxis.top}));this.translate();this.setTooltipPoints(!0);this.render();b&&aa(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=b.states,b=b.lineWidth,a=a||Ka;if(this.state!==a)this.state=a,d[a]&&d[a].enabled===!1||(a&&(b=d[a].lineWidth||b+1),c&&!c.dashstyle&&c.attr({"stroke-width":b},a?0:500))},setVisible:function(a,b){var c=this.chart,d=this.legendItem, -e=this.group,f=this.tracker,g=this.dataLabelsGroup,h,i=this.points,k=c.options.chart.ignoreHiddenSeries;h=this.visible;h=(this.visible=a=a===X?!h:a)?"show":"hide";if(e)e[h]();if(f)f[h]();else if(i)for(e=i.length;e--;)if(f=i[e],f.tracker)f.tracker[h]();if(g)g[h]();d&&c.legend.colorizeItem(this,a);this.isDirty=!0;this.options.stacking&&o(c.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});if(k)c.isDirtyBox=!0;b!==!1&&c.redraw();aa(this,h)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)}, -select:function(a){this.selected=a=a===X?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;aa(this,a?"select":"unselect")},drawTrackerGroup:function(){var a=this.trackerGroup,b=this.chart;if(this.isCartesian){if(!a)this.trackerGroup=a=b.renderer.g().attr({zIndex:this.options.zIndex||1}).add(b.trackerGroup);a.translate(this.xAxis.left,this.yAxis.top)}return a},drawTracker:function(){var a=this,b=a.options,c=[].concat(a.graphPath),d=c.length,e=a.chart,f=e.renderer,g=e.options.tooltip.snap,h= -a.tracker,i=b.cursor,i=i&&{cursor:i},k=a.singlePoints,j=a.drawTrackerGroup(),l;if(d)for(l=d+1;l--;)c[l]===wa&&c.splice(l+1,0,c[l+1]-g,c[l+2],fa),(l&&c[l]===wa||l===d)&&c.splice(l,0,fa,c[l-2]+g,c[l-1]);for(l=0;l<k.length;l++)d=k[l],c.push(wa,d.plotX-g,d.plotY,fa,d.plotX+g,d.plotY);h?h.attr({d:c}):a.tracker=f.path(c).attr({isTracker:!0,stroke:Gc,fill:Ma,"stroke-linejoin":"bevel","stroke-width":b.lineWidth+2*g,visibility:a.visible?eb:ab}).on(Ga?"touchstart":"mouseover",function(){if(e.hoverSeries!== -a)a.onMouseOver()}).on("mouseout",function(){if(!b.stickyTracking)a.onMouseOut()}).css(i).add(j)}};w=pa($);Ha.line=w;w=pa($,{type:"area"});Ha.area=w;w=pa($,{type:"spline",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,k,j;if(c&&c<a.length-1){a=f.plotY;k=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*e+a)/2.5;k=(1.5*d+k)/2.5;j=(1.5*e+g)/2.5;l=(j-i)*(k-d)/(k-h)+e-j;i+=l;j+=l;i>a&&i>e?(i=W(a,e),j=2*e-i):i<a&&i<e&&(i=Ua(a,e),j=2*e-i);j>g&&j>e?(j=W(g,e),i=2*e-j):j<g&& -j<e&&(j=Ua(g,e),i=2*e-j);b.rightContX=k;b.rightContY=j}c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=[wa,d,e];return b}});Ha.spline=w;w=pa(w,{type:"areaspline"});Ha.areaspline=w;var zb=pa($,{type:"column",tooltipOutsidePlot:!0,pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",r:"borderRadius"},init:function(){$.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type=== -a.type)b.isDirty=!0})},translate:function(){var a=this,b=a.chart,c=a.options,d=c.stacking,e=c.borderWidth,f=0,g=a.xAxis,h=g.reversed,i={},k,j;$.prototype.translate.apply(a);o(b.series,function(b){if(b.type===a.type&&b.visible&&a.options.group===b.options.group)b.options.stacking?(k=b.stackKey,i[k]===X&&(i[k]=f++),j=i[k]):j=f++,b.columnIndex=j});var b=a.points,g=Ba(g.translationSlope)*(g.ordinalSlope||g.closestPointRange||1),l=g*c.groupPadding,n=(g-2*l)/f,t=c.pointWidth,r=s(t)?(n-t)/2:n*c.pointPadding, -w=Yb(W(p(t,n-2*r),1+2*e)),x=r+(l+((h?f-a.columnIndex:a.columnIndex)||0)*n-g/2)*(h?-1:1),v=a.yAxis.getThreshold(c.threshold),y=p(c.minPointLength,5);o(b,function(b){var f=b.plotY,g=p(b.yBottom,v),h=b.plotX+x,i=Yb(Ua(f,g)),j=Yb(W(f,g)-i),k=a.yAxis.stacks[(b.y<0?"-":"")+a.stackKey];d&&a.visible&&k&&k[b.x]&&k[b.x].setOffset(x,w);Ba(j)<y&&y&&(j=y,i=Ba(i-v)>y?g-y:v-(f<=v?y:0));L(b,{barX:h,barY:i,barW:w,barH:j});b.shapeType="rect";f={x:h,y:i,width:w,height:j,r:c.borderRadius,strokeWidth:e};e%2&&(f.y-=1, -f.height+=1);b.shapeArgs=f;b.trackerArgs=Ba(j)<3&&K(b.shapeArgs,{height:6,y:i-3})})},getSymbol:function(){},drawGraph:function(){},drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d,e;o(a.points,function(f){var g=f.plotY;if(g!==X&&!isNaN(g)&&f.y!==null)d=f.graphic,e=f.shapeArgs,d?(Ob(d),d.animate(c.Element.prototype.crisp.apply({},[e.strokeWidth,e.x,e.y,e.width,e.height]))):f.graphic=d=c[f.shapeType](e).attr(f.pointAttr[f.selected?"select":Ka]).add(a.group).shadow(b.shadow)})},drawTracker:function(){var a= -this,b=a.chart,c=b.renderer,d,e,f=+new Date,g=a.options,h=g.cursor,i=h&&{cursor:h},k=a.drawTrackerGroup(),j;o(a.points,function(h){e=h.tracker;d=h.trackerArgs||h.shapeArgs;delete d.strokeWidth;if(h.y!==null)e?e.attr(d):h.tracker=c[h.shapeType](d).attr({isTracker:f,fill:Gc,visibility:a.visible?eb:ab}).on(Ga?"touchstart":"mouseover",function(c){j=c.relatedTarget||c.fromElement;if(b.hoverSeries!==a&&A(j,"isTracker")!==f)a.onMouseOver();h.onMouseOver()}).on("mouseout",function(b){if(!g.stickyTracking&& -(j=b.relatedTarget||b.toElement,A(j,"isTracker")!==f))a.onMouseOut()}).css(i).add(h.group||k)})},animate:function(a){var b=this,c=b.points,d=b.options;if(!a)o(c,function(a){var c=a.graphic,a=a.shapeArgs,g=b.yAxis,h=d.threshold;c&&(c.attr({height:0,y:s(h)?g.getThreshold(h):g.translate(g.getExtremes().min,0,1,0,1)}),c.animate({height:a.height,y:a.y},d.animation))}),b.animate=null},remove:function(){var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===a.type)b.isDirty=!0});$.prototype.remove.apply(a, -arguments)}});Ha.column=zb;w=pa(zb,{type:"bar",init:function(){this.inverted=!0;zb.prototype.init.apply(this,arguments)}});Ha.bar=w;w=pa($,{type:"scatter",sorted:!1,translate:function(){var a=this;$.prototype.translate.apply(a);o(a.points,function(b){b.shapeType="circle";b.shapeArgs={x:b.plotX,y:b.plotY,r:a.chart.options.tooltip.snap}})},drawTracker:function(){for(var a=this,b=a.options.cursor,b=b&&{cursor:b},c=a.points,d=c.length,e;d--;)if(e=c[d].graphic)e.element._i=d;a._hasTracking?a._hasTracking= -!0:a.group.attr({isTracker:!0}).on(Ga?"touchstart":"mouseover",function(b){a.onMouseOver();if(b.target._i!==X)c[b.target._i].onMouseOver()}).on("mouseout",function(){if(!a.options.stickyTracking)a.onMouseOut()}).css(b)}});Ha.scatter=w;w=pa(lb,{init:function(){lb.prototype.init.apply(this,arguments);var a=this,b;L(a,{visible:a.visible!==!1,name:p(a.name,"Slice")});b=function(){a.slice()};ha(a,"select",b);ha(a,"unselect",b);return a},setVisible:function(a){var b=this.series.chart,c=this.tracker,d=this.dataLabel, -e=this.connector,f=this.shadowGroup,g;g=(this.visible=a=a===X?!this.visible:a)?"show":"hide";this.group[g]();if(c)c[g]();if(d)d[g]();if(e)e[g]();if(f)f[g]();this.legendItem&&b.legend.colorizeItem(this,a)},slice:function(a,b,c){var d=this.series.chart,e=this.slicedTranslation;Kb(c,d);p(b,!0);a=this.sliced=s(a)?a:!this.sliced;a={translateX:a?e[0]:d.plotLeft,translateY:a?e[1]:d.plotTop};this.group.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}});w=pa($,{type:"pie",isCartesian:!1,pointClass:w, -pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:function(){this.initialColor=this.chart.counters.color},animate:function(){var a=this;o(a.points,function(b){var c=b.graphic,b=b.shapeArgs,d=-da/2;c&&(c.attr({r:0,start:d,end:d}),c.animate({r:b.r,start:b.start,end:b.end},a.options.animation))});a.animate=null},setData:function(){$.prototype.setData.apply(this,arguments);this.processData();this.generatePoints()},translate:function(){this.generatePoints();var a= -0,b=-0.25,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f=c.center.concat([c.size,c.innerSize||0]),g=this.chart,h=g.plotWidth,i=g.plotHeight,k,j,l,n=this.points,p=2*da,r,s=Ua(h,i),w,v,y,q=c.dataLabels.distance,f=Vb(f,function(a,b){return(w=/%$/.test(a))?[h,i,s,s][b]*S(a)/100:a});this.getX=function(a,b){l=oa.asin((a-f[1])/(f[2]/2+q));return f[0]+(b?-1:1)*ja(l)*(f[2]/2+q)};this.center=f;o(n,function(b){a+=b.y});o(n,function(c){r=a?c.y/a:0;k=z(b*p*1E3)/1E3;b+=r;j=z(b*p*1E3)/1E3;c.shapeType="arc"; -c.shapeArgs={x:f[0],y:f[1],r:f[2]/2,innerR:f[3]/2,start:k,end:j};l=(j+k)/2;c.slicedTranslation=Vb([ja(l)*d+g.plotLeft,C(l)*d+g.plotTop],z);v=ja(l)*f[2]/2;y=C(l)*f[2]/2;c.tooltipPos=[f[0]+v*0.7,f[1]+y*0.7];c.labelPos=[f[0]+v+ja(l)*q,f[1]+y+C(l)*q,f[0]+v+ja(l)*e,f[1]+y+C(l)*e,f[0]+v,f[1]+y,q<0?"center":l<p/4?"left":"right",l];c.percentage=r*100;c.total=a});this.setTooltipPoints()},render:function(){this.getAttribs();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();this.drawDataLabels(); -this.options.animation&&this.animate&&this.animate();this.isDirty=!1},drawPoints:function(){var a=this.chart,b=a.renderer,c,d,e,f=this.options.shadow,g,h;o(this.points,function(i){d=i.graphic;h=i.shapeArgs;e=i.group;g=i.shadowGroup;if(f&&!g)g=i.shadowGroup=b.g("shadow").attr({zIndex:4}).add();if(!e)e=i.group=b.g("point").attr({zIndex:5}).add();c=i.sliced?i.slicedTranslation:[a.plotLeft,a.plotTop];e.translate(c[0],c[1]);g&&g.translate(c[0],c[1]);d?d.animate(h):i.graphic=b.arc(h).attr(L(i.pointAttr[Ka], -{"stroke-linejoin":"round"})).add(i.group).shadow(f,g);i.visible===!1&&i.setVisible(!1)})},drawDataLabels:function(){var a=this.data,b,c=this.chart,d=this.options.dataLabels,e=p(d.connectorPadding,10),f=p(d.connectorWidth,1),g,h,i=p(d.softConnector,!0),k=d.distance,j=this.center,l=j[2]/2,j=j[1],n=k>0,t=[[],[]],r,s,w,v,y=2,q;if(d.enabled){$.prototype.drawDataLabels.apply(this);o(a,function(a){a.dataLabel&&t[a.labelPos[7]<da/2?0:1].push(a)});t[1].reverse();v=function(a,b){return b.y-a.y};for(a=t[0][0]&& -t[0][0].dataLabel&&t[0][0].dataLabel.getBBox().height;y--;){var x=[],A=[],z=t[y],E=z.length,C;for(q=j-l-k;q<=j+l+k;q+=a)x.push(q);w=x.length;if(E>w){h=[].concat(z);h.sort(v);for(q=E;q--;)h[q].rank=q;for(q=E;q--;)z[q].rank>=w&&z.splice(q,1);E=z.length}for(q=0;q<E;q++){b=z[q];h=b.labelPos;b=9999;for(s=0;s<w;s++)g=Ba(x[s]-h[1]),g<b&&(b=g,C=s);if(C<q&&x[q]!==null)C=q;else for(w<E-q+C&&x[q]!==null&&(C=w-E+q);x[C]===null;)C++;A.push({i:C,y:x[C]});x[C]=null}A.sort(v);for(q=0;q<E;q++){b=z[q];h=b.labelPos; -g=b.dataLabel;s=A.pop();r=h[1];w=b.visible===!1?ab:eb;C=s.i;s=s.y;if(r>s&&x[C+1]!==null||r<s&&x[C-1]!==null)s=r;r=this.getX(C===0||C===x.length-1?r:s,y);g.attr({visibility:w,align:h[6]})[g.moved?"animate":"attr"]({x:r+d.x+({left:e,right:-e}[h[6]]||0),y:s+d.y});g.moved=!0;if(n&&f)g=b.connector,h=i?[wa,r+(h[6]==="left"?5:-5),s,"C",r,s,2*h[2]-h[4],2*h[3]-h[5],h[2],h[3],fa,h[4],h[5]]:[wa,r+(h[6]==="left"?5:-5),s,fa,h[2],h[3],fa,h[4],h[5]],g?(g.animate({d:h}),g.attr("visibility",w)):b.connector=g=this.chart.renderer.path(h).attr({"stroke-width":f, -stroke:d.connectorColor||b.color||"#606060",visibility:w,zIndex:3}).translate(c.plotLeft,c.plotTop).add()}}}},drawTracker:zb.prototype.drawTracker,getSymbol:function(){}});Ha.pie=w;L(Highcharts,{Chart:wc,dateFormat:ac,pathAnim:La,getOptions:function(){return Ea},hasBidiBug:Qc,numberFormat:dc,Point:lb,Color:ma,Renderer:Xb,SVGRenderer:Eb,VMLRenderer:$a,CanVGRenderer:oc,seriesTypes:Ha,setOptions:function(a){$b=K($b,a.xAxis);kc=K(kc,a.yAxis);a.xAxis=a.yAxis=X;Ea=K(Ea,a);vc();return Ea},Series:$,addEvent:ha, -removeEvent:Qa,createElement:Aa,discardElement:Tb,css:P,each:o,extend:L,map:Vb,merge:K,pick:p,splat:Hb,extendClass:pa,placeBox:uc,product:"Highcharts",version:"2.2.1"})})(); diff --git a/apps/storage_charts/js/units.min.js b/apps/storage_charts/js/units.min.js deleted file mode 100644 index 5815f75fbb..0000000000 --- a/apps/storage_charts/js/units.min.js +++ /dev/null @@ -1,23 +0,0 @@ -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -function getLinesUsseUnitsSelect(s){$('#clines_usse h3').append('<span id="selunits"><span id="selloader"></span><select id="chunits"><option value="1"'+(s==1?' selected':'')+'>'+t('storage_charts','Kilobytes (KB)')+'</option><option value="2"'+(s==2?' selected':'')+'>'+t('storage_charts','Megabytes (MB)')+'</option><option value="3"'+(s==3?' selected':'')+'>'+t('storage_charts','Gigabytes (GB)')+'</option><option value="4"'+(s==4?' selected':'')+'>'+t('storage_charts','Terabytes (TB)')+'</option></select></span>');$('#chunits').chosen();$('#chunits').change(function(){$('#selloader').html('<img src="'+OC.imagePath('storage_charts','loader.gif')+'" />');$.ajax({type:'POST',url:OC.linkTo('storage_charts','ajax/data.php'),dataType:'json',data:{s:$('#chunits').val(),k:'hu_size'},async:true,success:function(s){eval(s.r);$('#selloader img').remove();}});});} -function getHistoUsUnitsSelect(s){$('#chisto_us h3').append('<span id="selunits_hus"><span id="selloader_hus"></span><select id="chunits_hus"><option value="1"'+(s==1?' selected':'')+'>'+t('storage_charts','Kilobytes (KB)')+'</option><option value="2"'+(s==2?' selected':'')+'>'+t('storage_charts','Megabytes (MB)')+'</option><option value="3"'+(s==3?' selected':'')+'>'+t('storage_charts','Gigabytes (GB)')+'</option><option value="4"'+(s==4?' selected':'')+'>'+t('storage_charts','Terabytes (TB)')+'</option></select></span>');$('#chunits_hus').chosen();$('#chunits_hus').change(function(){$('#selloader_hus').html('<img src="'+OC.imagePath('storage_charts','loader.gif')+'" />');$.ajax({type:'POST',url:OC.linkTo('storage_charts','ajax/data.php'),dataType:'json',data:{s:$('#chunits_hus').val(),k:'hu_size_hus'},async:true,success:function(s){eval(s.r);$('#selloader_hus img').remove();}});});} diff --git a/apps/storage_charts/l10n/de.php b/apps/storage_charts/l10n/de.php deleted file mode 100644 index e58e8acde2..0000000000 --- a/apps/storage_charts/l10n/de.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -* English texts -* -*/ - -$TRANSLATIONS = Array( - 'all users' => 'Alle Benutzer', - 'April' => 'April', - 'August' => 'August', - 'December' => 'Dezember', - 'February' => 'Februar', - 'January' => 'Januar', - 'July' => 'Juli', - 'June' => 'Juni', - 'March' => 'März', - 'May' => 'Mai', - 'November' => 'November', - 'October' => 'Oktober', - 'September' => 'September', - 'Monthly Used Space Evolution' => 'Entwicklung des monatlich genutzten Speichers', - 'Last 7 days' => 'Die letzten 7 Tage', - 'Daily Used Space Evolution' => 'Entwicklung des täglich genutzten Speichers', - 'Current ratio free space / used space' => 'Aktuelles Verhältnis zwischen freier Speicher / genutzter Speicher', - 'for' => 'für', - 'Free space' => 'Freier Speicher', - 'Drag\'N\'Drop on the chart title to re-order' => 'Drag\'N\'Drop der Diagrammnamen zum neuordnern', - 'Gigabytes (GB)' => 'Gigabytes (GB)', - 'Kilobytes (KB)' => 'Kilobytes (KB)', - 'Megabytes (MB)' => 'Megabytes (MB)', - 'Terabytes (TB)' => 'Terabytes (TB)', - 'Used space' => 'Genutzter Speicher', - 'Average used space' => 'Durchschnittlich verbrauchter Speicher', - - // Personal settings - 'Save' => 'Speichern', - 'Save OK' => 'Speichern erfolgreich', - 'Uncheck charts you do not want to display' => 'Diagramme abwählen die nicht angezeigt werden sollen' -); \ No newline at end of file diff --git a/apps/storage_charts/l10n/en.php b/apps/storage_charts/l10n/en.php deleted file mode 100644 index 7676107aa3..0000000000 --- a/apps/storage_charts/l10n/en.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -* English texts -* -*/ - -$TRANSLATIONS = Array( - 'all users' => 'all users', - 'April' => 'April', - 'August' => 'August', - 'Average used space' => 'Average used space', - 'December' => 'December', - 'February' => 'February', - 'January' => 'January', - 'July' => 'July', - 'June' => 'June', - 'March' => 'March', - 'May' => 'May', - 'November' => 'November', - 'October' => 'October', - 'September' => 'September', - 'Monthly Used Space Evolution' => 'Monthly Used Space Evolution', - 'Last 7 days' => 'Last 7 days', - 'Daily Used Space Evolution' => 'Daily Used Space Evolution', - 'Current ratio free space / used space' => 'Current ratio free space / used space', - 'for' => 'for', - 'Free space' => 'Free space', - 'Drag\'N\'Drop on the chart title to re-order' => 'Drag\'N\'Drop on the chart title to re-order', - 'Gigabytes (GB)' => 'Gigabytes (GB)', - 'Kilobytes (KB)' => 'Kilobytes (KB)', - 'Megabytes (MB)' => 'Megabytes (MB)', - 'Terabytes (TB)' => 'Terabytes (TB)', - 'Used space' => 'Used space', - - // Personal settings - 'Save' => 'Save', - 'Save OK' => 'Save OK', - 'Uncheck charts you do not want to display' => 'Uncheck charts you do not want to display' -); \ No newline at end of file diff --git a/apps/storage_charts/l10n/fr.php b/apps/storage_charts/l10n/fr.php deleted file mode 100644 index 9d1b23b34d..0000000000 --- a/apps/storage_charts/l10n/fr.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -* French texts -* -*/ - -$TRANSLATIONS = Array( - 'all users' => 'tous les utilisateurs', - 'April' => 'Avril', - 'August' => 'Août', - 'December' => 'Décembre', - 'February' => 'Février', - 'January' => 'Janvier', - 'July' => 'Juillet', - 'June' => 'Juin', - 'March' => 'Mars', - 'May' => 'Mai', - 'November' => 'Novembre', - 'October' => 'Octobre', - 'September' => 'Septembre', - 'Monthly Used Space Evolution' => 'Evolution mensuelle de l\'espace utilisé', - 'Last 7 days' => 'Les 7 derniers jours', - 'Daily Used Space Evolution' => 'Evolution quotidienne de l\'espace utilisé', - 'Current ratio free space / used space' => 'Ratio Espace libre / Espace utilisé actuel', - 'for' => 'pour', - 'Free space' => 'Espace libre', - 'Drag\'N\'Drop on the chart title to re-order' => 'Drag\'N\'Drop sur le titre du graph pour changer l\'ordre', - 'Gigabytes (GB)' => 'Gigabytes (GB)', - 'Kilobytes (KB)' => 'Kilobytes (KB)', - 'Megabytes (MB)' => 'Megabytes (MB)', - 'Terabytes (TB)' => 'Terabytes (TB)', - 'Used space' => 'Espace utilisé', - 'Average used space' => 'Espace utilisé moyen', - - // Personal settings - 'Save' => 'Enregistrer', - 'Save OK' => 'Enregistrement OK', - 'Uncheck charts you do not want to display' => 'Décochez les graphs que vous ne voulez pas afficher' -); \ No newline at end of file diff --git a/apps/storage_charts/l10n/pt_BR.php b/apps/storage_charts/l10n/pt_BR.php deleted file mode 100644 index 823e19a6ed..0000000000 --- a/apps/storage_charts/l10n/pt_BR.php +++ /dev/null @@ -1,59 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -* Portuguese texts -* 26/May/2012 - Translated by Tiago Soares (tbsoares@gmail.com) -* -*/ - -$TRANSLATIONS = Array( - 'all users' => 'Todos os usuários', - 'April' => 'Abril', - 'August' => 'Agosto', - 'Average used space' => 'Média de espaço utilizado', - 'December' => 'Dezembro', - 'February' => 'Fevereiro', - 'January' => 'Janeiro', - 'July' => 'Julho', - 'June' => 'Junho', - 'March' => 'Março', - 'May' => 'Maio', - 'November' => 'Novembro', - 'October' => 'Outubro', - 'September' => 'Setembro', - 'Monthly Used Space Evolution' => 'Evolução mensal do espaço utilizado', - 'Last 7 days' => 'Últimos 7 dias', - 'Daily Used Space Evolution' => 'Evolução diária do espaço utilizado', - 'Current ratio free space / used space' => 'Proporção atual entre espaço livre / espaço utilizado', - 'for' => 'para', - 'Free space' => 'Espaço livre', - 'Drag\'N\'Drop on the chart title to re-order' => 'Arraste e solte no título do gráfico para reordenar', - 'Gigabytes (GB)' => 'Gigabytes (GB)', - 'Kilobytes (KB)' => 'Kilobytes (KB)', - 'Megabytes (MB)' => 'Megabytes (MB)', - 'Terabytes (TB)' => 'Terabytes (TB)', - 'Used space' => 'Espaço utlizado', - - // Personal settings - 'Save' => 'Salvar', - 'Save OK' => 'Salvo', - 'Uncheck charts you do not want to display' => 'Desmarque os gráficos que não deseja exibir' -); diff --git a/apps/storage_charts/lib/db.class.php b/apps/storage_charts/lib/db.class.php deleted file mode 100644 index 4479622180..0000000000 --- a/apps/storage_charts/lib/db.class.php +++ /dev/null @@ -1,290 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * This class manages storage_charts. - */ -class OC_DLStCharts { - - /** - * UPDATE day use for a user - * @param $used user used space - * @param $total total users used space - */ - public static function update($used, $total){ - $query = OCP\DB::prepare("SELECT stc_id FROM *PREFIX*dlstcharts WHERE oc_uid = ? AND stc_dayts = ?"); - $result = $query->execute(Array(OCP\User::getUser(), mktime(0,0,0)))->fetchRow(); - if($result){ - $query = OCP\DB::prepare("UPDATE *PREFIX*dlstcharts SET stc_used = ?, stc_total = ? WHERE stc_id = ?"); - $query->execute(Array($used, $total, $result['stc_id'])); - }else{ - $query = OCP\DB::prepare("INSERT INTO *PREFIX*dlstcharts (oc_uid,stc_month,stc_dayts,stc_used,stc_total) VALUES (?,?,?,?,?)"); - $query->execute(Array(OCP\User::getUser(), date('Ym'), mktime(0,0,0), $used, $total)); - } - } - - /** - * Get the size of the data folder - * @param $path path to the folder you want to calculate the total size - */ - public static function getTotalDataSize($path){ - if(is_file($path)){ - $path = dirname($path); - } - $path = str_replace('//', '/', $path); - if(is_dir($path) and strcmp(substr($path, -1), '/') != 0){ - $path .= '/'; - } - $size = 0; - if($dh = opendir($path)){ - while(($filename = readdir($dh)) !== false) { - if(strcmp($filename, '.') != 0 and strcmp($filename, '..') != 0){ - $subFile = $path . '/' . $filename; - if(is_file($subFile)){ - $size += filesize($subFile); - }else{ - $size += self::getTotalDataSize($subFile); - } - } - } - } - return $size; - } - - /** - * Get data to build the pie about the Free-Used space ratio - */ - public static function getPieFreeUsedSpaceRatio(){ - if(OC_Group::inGroup(OCP\User::getUser(), 'admin')){ - $query = OCP\DB::prepare("SELECT stc_id, stc_dayts, oc_uid FROM (SELECT * FROM *PREFIX*dlstcharts ORDER BY stc_dayts DESC) last GROUP BY oc_uid"); - $results = $query->execute()->fetchAll(); - }else{ - $query = OCP\DB::prepare("SELECT stc_id, MAX(stc_dayts) as stc_dayts FROM *PREFIX*dlstcharts WHERE oc_uid = ?"); - $results = $query->execute(Array(OCP\User::getUser()))->fetchAll(); - } - - $return = Array(); - foreach($results as $result){ - $query = OCP\DB::prepare("SELECT oc_uid, stc_used, stc_total FROM *PREFIX*dlstcharts WHERE stc_id = ?"); - $return[] = $query->execute(Array($result['stc_id']))->fetchAll(); - } - - return $return; - } - - /** - * Get data to build the line chart about last 7 days used space evolution - */ - public static function getUsedSpaceOverTime($time){ - $return = Array(); - if(OC_Group::inGroup(OCP\User::getUser(), 'admin')){ - foreach(OCP\User::getUsers() as $user){ - if(strcmp($time, 'daily') == 0){ - $return[$user] = self::getDataByUserToLineChart($user); - }else{ - $return[$user] = self::getDataByUserToHistoChart($user); - } - } - }else{ - if(strcmp($time, 'daily') == 0){ - $return[OCP\User::getUser()] = self::getDataByUserToLineChart(OCP\User::getUser()); - }else{ - $return[OCP\User::getUser()] = self::getDataByUserToHistoChart(OCP\User::getUser()); - } - } - return $return; - } - - /** - * Get configuration values stored in the database - * @param $key The conf key - * @return Array The conf value - */ - public static function getUConfValue($key, $default = NULL){ - $query = OCP\DB::prepare("SELECT uc_id,uc_val FROM *PREFIX*dlstcharts_uconf WHERE oc_uid = ? AND uc_key = ?"); - $result = $query->execute(Array(OCP\User::getUser(), $key))->fetchRow(); - if($result){ - return $result; - } - return $default; - } - - /** - * Set configuration values stored in the database - * @param $key The conf key - * @param $val The conf value - */ - public static function setUConfValue($key,$val){ - $conf = self::getUConfValue($key); - if(!is_null($conf)){ - $query = OCP\DB::prepare("UPDATE *PREFIX*dlstcharts_uconf SET uc_val = ? WHERE uc_id = ?"); - $query->execute(Array($val, $conf['uc_id'])); - }else{ - $query = OCP\DB::prepare("INSERT INTO *PREFIX*dlstcharts_uconf (oc_uid,uc_key,uc_val) VALUES (?,?,?)"); - $query->execute(Array(OCP\User::getUser(), $key, $val)); - } - } - - /** - * Parse an array and return data in the highCharts format - * @param $operation operation to do - * @param $elements elements to parse - */ - public static function arrayParser($operation, $elements, $l, $data_sep = ',', $ck = 'hu_size'){ - $return = ""; - switch($operation){ - case 'pie': - $free = $total = 0; - foreach($elements as $element){ - $element = $element[0]; - - $total = $element['stc_total']; - $free += $element['stc_used']; - - $return .= "['" . $element['oc_uid'] . "', " . $element['stc_used'] . "],"; - } - $return .= "['" . $l->t('Free space') . "', " . ($total - $free) . "]"; - break; - case 'histo': - case 'line': - $conf = self::getUConfValue($ck, Array('uc_val' => 3)); - $div = 1; - switch($conf['uc_val']){ - case 4: - $div = 1024; - case 3: - $div *= 1024; - case 2: - $div *= 1024; - case 1: - $div *= 1024; - } - - foreach($elements as $user => $data){ - $return_tmp = '{"name":"' . $user . '","data":['; - foreach($data as $number){ - $return_tmp .= round($number/$div, 2) . ","; - } - $return_tmp = substr($return_tmp, 0, -1) . "]}"; - - $return .= $return_tmp . $data_sep; - } - $return = substr($return, 0, -(strlen($data_sep))); - break; - } - return $return; - } - - /** - * Get data by user for Seven Days Line Chart - * @param $user the user - * @return Array - */ - private static function getDataByUserToLineChart($user){ - $dates = Array( - mktime(0,0,0,date('m'),date('d')-6), - mktime(0,0,0,date('m'),date('d')-5), - mktime(0,0,0,date('m'),date('d')-4), - mktime(0,0,0,date('m'),date('d')-3), - mktime(0,0,0,date('m'),date('d')-2), - mktime(0,0,0,date('m'),date('d')-1), - mktime(0,0,0,date('m'),date('d')) - ); - - $return = Array(); - foreach($dates as $kd => $date){ - $query = OCP\DB::prepare("SELECT stc_used FROM *PREFIX*dlstcharts WHERE oc_uid = ? AND stc_dayts = ?"); - $result = $query->execute(Array($user, $date))->fetchAll(); - - if(count($result) > 0){ - $return[] = $result[0]['stc_used']; - }else{ - if($kd == 0){ - $query = OCP\DB::prepare("SELECT stc_used FROM *PREFIX*dlstcharts WHERE oc_uid = ? AND stc_dayts < ? ORDER BY stc_dayts DESC"); - $result = $query->execute(Array($user, $date))->fetchAll(); - - if(count($result) > 0){ - $return[] = $result[0]['stc_used']; - }else{ - $return[] = 0; - } - }else{ - $return[] = 0; - } - } - } - - $last = 0; - foreach ($return as $key => $value) { - if($value == 0){ - $return[$key] = $last; - } - $last = $return[$key]; - } - return $return; - } - - /** - * Get data by users for monthly evolution - * @param $user The user - * @return Array - */ - private static function getDataByUserToHistoChart($user){ - $months = Array( - date('Ym',mktime(0,0,0,date('m')-11)), - date('Ym',mktime(0,0,0,date('m')-10)), - date('Ym',mktime(0,0,0,date('m')-9)), - date('Ym',mktime(0,0,0,date('m')-8)), - date('Ym',mktime(0,0,0,date('m')-7)), - date('Ym',mktime(0,0,0,date('m')-6)), - date('Ym',mktime(0,0,0,date('m')-5)), - date('Ym',mktime(0,0,0,date('m')-4)), - date('Ym',mktime(0,0,0,date('m')-3)), - date('Ym',mktime(0,0,0,date('m')-2)), - date('Ym',mktime(0,0,0,date('m')-1)), - date('Ym',mktime(0,0,0,date('m'))) - ); - - $return = Array(); - foreach($months as $km => $month){ - $query = OCP\DB::prepare("SELECT AVG(stc_used) as stc_used FROM *PREFIX*dlstcharts WHERE oc_uid = ? AND stc_month = ?"); - $result = $query->execute(Array($user, $month))->fetchAll(); - - if(count($result) > 0){ - $return[] = $result[0]['stc_used']; - }else{ - $return[] = 0; - } - } - - $last = 0; - foreach ($return as $key => $value) { - if($value == 0){ - $return[$key] = $last; - } - $last = $return[$key]; - } - return $return; - } - -} \ No newline at end of file diff --git a/apps/storage_charts/lib/loader.class.php b/apps/storage_charts/lib/loader.class.php deleted file mode 100644 index 3df5abe584..0000000000 --- a/apps/storage_charts/lib/loader.class.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -/** - * This class load charts for storage_charts. - */ -class OC_DLStChartsLoader { - - private static $l; - - /** - * Loader - * @param $chart_id The chart iD - * @return String - */ - public static function loadChart($chart_id, $l){ - self::$l = $l; - - switch($chart_id){ - case 'cpie_rfsus': - return self::loadPieFreeUsedSpaceRatioChart(); - break; - case 'clines_usse': - return self::loadLinesLastSevenDaysUsedSpaceChart(); - break; - case 'chisto_us': - return self::loadHistoMonthlyUsedSpaceChart(); - break; - } - } - - /** - * Get free/used space ratio chart - * @return String - */ - private static function loadPieFreeUsedSpaceRatioChart(){ - return 'pierfsus=new Highcharts.Chart({chart:{renderTo:\'pie_rfsus\',backgroundColor:\'#F8F8F8\',plotBackgroundColor:\'#F8F8F8\',plotBorderWidth:false,plotShadow:false},title:{text:\'\'},tooltip:{formatter:function(){return \'<b>\'+this.point.name+\'</b>: \'+(Math.round(this.percentage*100)/100)+\' %\';}},plotOptions:{pie:{allowPointSelect:true,cursor:\'pointer\',dataLabels:{enabled:true,color:\'#000000\',connectorColor:\'#000000\',formatter:function(){return\'<b>\'+this.point.name+\'</b>: \'+Math.round(this.percentage)+\' %\';}}}},series:[{type:\'pie\',name:\'Used-Free space ratio\',data:[' . OC_DLStCharts::arrayParser('pie',OC_DLStCharts::getPieFreeUsedSpaceRatio(), self::$l) . ']}],exporting:{enabled:false}});'; - } - - /** - * Get seven days used space evolution chart - * @return String - */ - private static function loadLinesLastSevenDaysUsedSpaceChart(){ - $units = Array('', 'KB', 'MB', 'GB', 'TB'); - $u = OC_DLStCharts::getUConfValue('hu_size', Array('uc_val' => 3)); - $u = $units[$u['uc_val']]; - return 'linesusse=new Highcharts.Chart({chart:{renderTo:\'lines_usse\',backgroundColor:\'#F8F8F8\',plotBackgroundColor:\'#F8F8F8\',type:\'line\'},title:{text:\'\'},subtitle:{text:\''.self::$l->t('Last 7 days').'\',x:-20},xAxis:{categories:["'.date('m/d', mktime(0,0,0,date('m'),date('d')-6)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d')-5)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d')-4)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d')-3)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d')-2)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d')-1)).'","'.date('m/d', mktime(0,0,0,date('m'),date('d'))).'"]},yAxis:{title:{text:\''.self::$l->t('Used space').' ('.$u.')\'},plotLines:[{value:0,width:1,color:\'#808080\'}],startOnTick:false,min:0},tooltip:{crosshairs:true,formatter:function(){return \'<b>\'+this.series.name+\'</b><br/>\'+this.x+\': \'+this.y+\' '.$u.'\';}},legend:{layout:\'horizontal\',align:\'center\',verticalAlign:\'top\',x:-25,y:40,borderWidth:0},series:['.OC_DLStCharts::arrayParser('line', OC_DLStCharts::getUsedSpaceOverTime('daily'), self::$l).'],exporting:{enabled:false}});'; - } - - /** - * Get monthly used space evolution chart - * @return String - */ - private static function loadHistoMonthlyUsedSpaceChart(){ - $units = Array('', 'KB', 'MB', 'GB', 'TB'); - $u = OC_DLStCharts::getUConfValue('hu_size_hus', Array('uc_val' => 3)); - $u = $units[$u['uc_val']]; - - $months = self::getMonths(); - - return 'histous=new Highcharts.Chart({chart:{renderTo:\'histo_us\',backgroundColor:\'#F8F8F8\',plotBackgroundColor:\'#F8F8F8\',type:\'column\'},title:{text:\'\'},xAxis:{categories:["'.self::$l->t($months[0]).' '.date('Y',mktime(0,0,0,date('m')-11)).'","'.self::$l->t($months[1]).' '.date('Y',mktime(0,0,0,date('m')-10)).'","'.self::$l->t($months[2]).' '.date('Y',mktime(0,0,0,date('m')-9)).'","'.self::$l->t($months[3]).' '.date('Y',mktime(0,0,0,date('m')-8)).'","'.self::$l->t($months[4]).' '.date('Y',mktime(0,0,0,date('m')-7)).'","'.self::$l->t($months[5]).' '.date('Y',mktime(0,0,0,date('m')-6)).'","'.self::$l->t($months[6]).' '.date('Y',mktime(0,0,0,date('m')-5)).'","'.self::$l->t($months[7]).' '.date('Y',mktime(0,0,0,date('m')-4)).'","'.self::$l->t($months[8]).' '.date('Y',mktime(0,0,0,date('m')-3)).'","'.self::$l->t($months[9]).' '.date('Y',mktime(0,0,0,date('m')-2)).'","'.self::$l->t($months[10]).' '.date('Y',mktime(0,0,0,date('m')-1)).'","'.self::$l->t($months[11]).' '.date('Y',mktime(0,0,0,date('m'))).'"]},yAxis:{min:0,title:{text:\''.self::$l->t('Average used space').' ('.$u.')\'},stackLabels:{enabled:true,style:{fontWeight:\'bold\',color:(Highcharts.theme&&Highcharts.theme.textColor)||\'gray\'},formatter:function(){return(Math.round(this.total*100)/100);}}},legend:{align:\'center\',x:-20,verticalAlign:\'top\',y:20,floating:true,backgroundColor:(Highcharts.theme&&Highcharts.theme.legendBackgroundColorSolid)||\'white\',borderColor:\'#CCC\',borderWidth:1,shadow:false},tooltip:{formatter:function(){return \'<b>\'+this.x+\'</b><br/>\'+this.series.name+\': \'+(Math.round(this.y*100)/100)+\' '.$u.'<br/>\'+\'Total: \'+(Math.round(this.point.stackTotal*100)/100)+\' '.$u.'\';}},plotOptions:{column:{stacking:\'normal\',dataLabels:{enabled:false,color:(Highcharts.theme&&Highcharts.theme.dataLabelsColor)||\'white\'}}},series:['.OC_DLStCharts::arrayParser('histo',OC_DLStCharts::getUsedSpaceOverTime('monthly'),self::$l,',','hu_size_hus').'],exporting:{enabled:false}});'; - } - - /** - * Get months - */ - private static function getMonths(){ - $months = Array('January','February','March','April','May','June','July','August','September','October','November','December'); - - $tmp = Array(); - for($i=date('n');$i<12;$i++){ - $tmp[] = $months[$i]; - } - for($i=0;$i<date('n');$i++){ - $tmp[] = $months[$i]; - } - - return $tmp; - } - -} \ No newline at end of file diff --git a/apps/storage_charts/settings.php b/apps/storage_charts/settings.php deleted file mode 100644 index 6a43684452..0000000000 --- a/apps/storage_charts/settings.php +++ /dev/null @@ -1,43 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -OCP\User::checkLoggedIn(); -OCP\App::checkAppEnabled('storage_charts'); - -$tmpl = new OCP\Template('storage_charts', 'settings.tpl'); - -if(isset($_POST['storage_charts_disp']) && count($_POST['storage_charts_disp']) <= 3){ - $c = $_POST['storage_charts_disp']; - $c_disp = Array('cpie_rfsus'=>0,'clines_usse'=>0,'chisto_us'=>0); - foreach(array_keys($c_disp) as $chart){ - if(in_array($chart, $c)){ - $c_disp[$chart] = 1; - } - } - OC_DLStCharts::setUConfValue('c_disp', serialize($c_disp)); - $tmpl->assign('stc_save_ok', TRUE); -} - -$displays = OC_DLStCharts::getUConfValue('c_disp', Array('uc_val' => 'a:3:{s:10:"cpie_rfsus";i:1;s:11:"clines_usse";i:1;s:9:"chisto_us";i:1;}')); -$tmpl->assign('displays', unserialize($displays['uc_val'])); -return $tmpl->fetchPage(); \ No newline at end of file diff --git a/apps/storage_charts/templates/charts.tpl.php b/apps/storage_charts/templates/charts.tpl.php deleted file mode 100644 index 98d20706df..0000000000 --- a/apps/storage_charts/templates/charts.tpl.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -* JS minified by http://fmarcia.info/jsmin/test.html -* -*/ - -OCP\Util::addStyle('storage_charts', 'styles'); -OCP\Util::addScript('storage_charts', 'highCharts-2.2.1/highcharts.min'); -OCP\Util::addScript('3rdparty','chosen/chosen.jquery.min'); -OCP\Util::addStyle('3rdparty','chosen'); -OCP\Util::addScript('storage_charts', 'units.min'); - -?> - -<script type="text/javascript"> - $(document).ready(function(){ - $('#stc_sortable').sortable({ - axis:'y',handle:'h3',placeholder:'ui-state-highlight',update:function(e,u){ - $.ajax({ - type:'POST', - url:OC.linkTo('storage_charts','ajax/config.php'), - dataType:'json', - data:{o:'set',k:'sc_sort',i:$('#stc_sortable').sortable('toArray')}, - async:true - }); - } - }); - $('#stc_sortable').disableSelection(); - }); -</script> - -<div id="storage-charts"> - <div class="personalblock topblock titleblock"> - DjazzLab Storage Charts<span><?php print($l->t('Drag\'N\'Drop on the chart title to re-order')); ?></span> - </div> -</div> -<div id="stc_frame"> - <div id="stc_sortable"> - <?php foreach($_['sc_sort'] as $sc_sort){ - if(strcmp($sc_sort, 'cpie_rfsus') == 0){ - $sc_sort_title = 'Current ratio free space / used space'; - }elseif(strcmp($sc_sort, 'clines_usse') == 0){ - $sc_sort_title = 'Daily Used Space Evolution'; - }else{ - $sc_sort_title = 'Monthly Used Space Evolution'; - } - if($_['c_disp'][$sc_sort]){ ?> - <div id="<?php print($sc_sort); ?>" class="personalblock"> - <h3><img src="<?php print(OCP\Util::imagePath('storage_charts', 'move.png')); ?>" /><?php print($l->t($sc_sort_title).' '.$l->t('for')); ?> "<?php print(OC_Group::inGroup(OCP\User::getUser(), 'admin')?$l->t('all users'):OCP\User::getUser()); ?>"</h3> - <div id="<?php print(substr($sc_sort, 1)); ?>" style="max-width:100%;height:400px;margin:0 auto"></div> - <script type="text/javascript">$(document).ready(function(){<?php print(OC_DLStChartsLoader::loadChart($sc_sort, $l)); ?>});</script> - </div> - <?php } - } ?> - </div> - <?php if($_['c_disp']['clines_usse']){print('<script type="text/javascript">$(document).ready(function(){getLinesUsseUnitsSelect('.$_['hu_size'].');});</script>');} - if($_['c_disp']['chisto_us']){print('<script type="text/javascript">$(document).ready(function(){getHistoUsUnitsSelect(' . $_['hu_size_hus'] . ');});</script>');} ?> -</div> \ No newline at end of file diff --git a/apps/storage_charts/templates/settings.tpl.php b/apps/storage_charts/templates/settings.tpl.php deleted file mode 100644 index 6b86850c93..0000000000 --- a/apps/storage_charts/templates/settings.tpl.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php - -/** -* ownCloud - DjazzLab Storage Charts plugin -* -* @author Xavier Beurois -* @copyright 2012 Xavier Beurois www.djazz-lab.net -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ - -?> -<form id="storage_charts" method="POST" action="<?php print(OC_Helper::linkTo('settings','personal.php')); ?>"> - <fieldset class="personalblock"> - <strong>DjazzLab Storage Charts</strong><span style="margin-left:10px;color:#BBB;font-style:italic;"><?php print($l->t('Uncheck charts you do not want to display')); ?></span> - <?php foreach($_['displays'] as $chart => $is_enable){ - if(strcmp($chart, 'cpie_rfsus') == 0){ - $chart_title = 'Current ratio free space / used space'; - }elseif(strcmp($chart, 'clines_usse') == 0){ - $chart_title = 'Daily Used Space Evolution'; - }else{ - $chart_title = 'Monthly Used Space Evolution'; - } ?> - <div><input type="checkbox" name="storage_charts_disp[]" id="<?php print($chart); ?>_e" style="margin-right:10px;"<?php print($is_enable?' checked':'') ?> value="<?php print($chart); ?>" /><?php print($l->t($chart_title)); ?></div> - <?php } ?> - <input type="submit" value="<?php print($l->t('Save')); ?>" /><span style="color:#00A220;"><?php if(isset($_['stc_save_ok'])){print($l->t('Save OK'));} ?></span> - </fieldset> -</form> diff --git a/apps/tal/.gitignore b/apps/tal/.gitignore deleted file mode 100644 index e2ff07d14d..0000000000 --- a/apps/tal/.gitignore +++ /dev/null @@ -1,51 +0,0 @@ -# the default generated dir + db file -data -owncloud -config/config.php -config/mount.php -apps/inc.php - -# just sane ignores -.*.sw[po] -*.bak -*.BAK -*~ -*.orig -*.class -.cvsignore -Thumbs.db -*.py[co] -_darcs/* -CVS/* -.svn/* -RCS/* - -# kdevelop -.kdev -*.kdev4 - -# Lokalize -*lokalize* - -# eclipse -.project -.settings - -# netbeans -nbproject - -# geany -*.geany - -# Cloud9IDE -.settings.xml - -# vim ex mode -.vimrc - -# Mac OS -.DS_Store - -# WebFinger -.well-known -/.buildpath diff --git a/apps/tal/COPYING-AGPL b/apps/tal/COPYING-AGPL deleted file mode 100644 index dba13ed2dd..0000000000 --- a/apps/tal/COPYING-AGPL +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -<http://www.gnu.org/licenses/>. diff --git a/apps/tal/COPYING-README b/apps/tal/COPYING-README deleted file mode 100644 index 18f06caa3e..0000000000 --- a/apps/tal/COPYING-README +++ /dev/null @@ -1,10 +0,0 @@ -Files in TAL Templating System for ownCloud are licensed under the Affero General Public License version 3, -the text of which can be found in COPYING-AGPL, or any later version of the AGPL, -unless otherwise noted. - -Licensing of components: -* PHPTAL - http://phptal.org/ : LGPL - -All unmodified files from these and other sources retain their original copyright -and license notices: see the relevant individual files. - diff --git a/apps/tal/README.md b/apps/tal/README.md deleted file mode 100644 index 756221c07a..0000000000 --- a/apps/tal/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# TAL Page Templates for ownCloud - -Develop using the Template Attribute Language instead of having clumsy -`<?php echo $var; ?>` tags in your markup. - -Read more at the [PHPTAL site](http://phptal.org/introduction.html) - -## Install from git - -1. Go to your ownCloud apps dir and clone the repo there: - <pre> - cd owncloud/apps - git clone git://github.com/tanghus/tal.git - </pre> - -2. Go to the `lib`directory of the newly created `tal` folder and clone the [PHPTAL repo](https://github.com/pornel/PHPTAL): - - <pre> - cd tal/lib - git clone git://github.com/pornel/PHPTAL.git - </pre> - -3. From your browser go to the ownCloud apps page (`/settings/apps.php`) and enable the "TAL Page Templates for ownCloud" app. - -4. Go to the Personal page (`/settings/personal.php`) and check if the installation has succeeded. You will find a section with a link to the manual. - diff --git a/apps/tal/TODO b/apps/tal/TODO deleted file mode 100644 index ef1e495249..0000000000 --- a/apps/tal/TODO +++ /dev/null @@ -1,2 +0,0 @@ -TODO -- Create script to extract translatable strings. diff --git a/apps/tal/ajax/loadpage.php b/apps/tal/ajax/loadpage.php deleted file mode 100644 index f6a1499f45..0000000000 --- a/apps/tal/ajax/loadpage.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php -/** - * Copyright (c) 2011 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('tal'); - -$id = isset($_GET['id'])?trim(strip_tags($_GET['id'])):''; - -if($id) { - $tmpl = new OC_TALTemplate('tal', 'sections'); - $tmpl->assign('id',$id); - $page = $tmpl->fetchPage(); - OCP\JSON::success(array('data' => array('id'=>$id, 'page'=>$page))); - exit(); -} else { - $l10n = new OC_L10N('tal'); - OCP\JSON::error(array('data' => array('message' => $l10n->t('Page name missing from request.')))); -} \ No newline at end of file diff --git a/apps/tal/appinfo/app.php b/apps/tal/appinfo/app.php deleted file mode 100644 index 65c1c4b5bd..0000000000 --- a/apps/tal/appinfo/app.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php -OC::$CLASSPATH['OC_TALTemplate'] = 'tal/lib/taltemplate.php'; -OC::$CLASSPATH['OC_TALL10N'] = 'tal/lib/tall10n.php'; -OC::$CLASSPATH['PHPTAL'] = 'tal/lib/PHPTAL/classes/PHPTAL.php'; -OC::$CLASSPATH['PHPTAL_TranslationService'] = 'tal/lib/PHPTAL/classes/PHPTAL/TranslationService.php'; - -OCP\App::register( array( - 'id' => 'tal', - 'name' => 'TAL Page Templates' )); - -OCP\App::registerPersonal('tal','settings'); \ No newline at end of file diff --git a/apps/tal/appinfo/info.xml b/apps/tal/appinfo/info.xml deleted file mode 100644 index 40224f29ff..0000000000 --- a/apps/tal/appinfo/info.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0"?> -<info> - <id>tal</id> - <name>TAL Page Templates for ownCloud</name> - <description>This is an alternative to OC_Template and OC_L10N - the templating and internationalization classes used in ownCloud. - </description> - <version>0.1</version> - <licence>AGPL</licence> - <author>Thomas Tanghus</author> - <require>5</require> -</info> diff --git a/apps/tal/css/tal.css b/apps/tal/css/tal.css deleted file mode 100644 index ed51bc5038..0000000000 --- a/apps/tal/css/tal.css +++ /dev/null @@ -1,25 +0,0 @@ -#manual { - float: left; - position: absolute; left: 0; top: 0; right: 0; bottom: 0; - margin: 0.5em; - padding: 1em; - overflow: auto; - background-color :#f8f8f8; - color: #555; - border: 1px solid #ddd; - border-radius: 0.5em 0.5em 0.5em 0.5em; - -webkit-transition:background-color 200ms; -moz-transition:background-color 200ms; -o-transition:background-color 200ms; transition:background-color 200ms; -} -#manual nav { position: fixed; top: 5em; width: 15%; font-weight: bold; font-size: 1.2em; } -#manual ol { list-style: decimal; padding-left: 3em; } -#manual section { float:right; width: 80%; height: 95%; padding: 1em; font-size: 1.2em; } -#manual a { color: #555; } -#manual a:hover { color: #333; } -#manual li:hover { color: #333; background-color:#eee; } -code, pre { font-family: "Lucida Console", "Lucida Sans Typewriter", "DejaVu Sans Mono", monospace; } -code { margin: 0; padding: 0; } -pre { overflow:auto; display:block; margin: 1em; padding: 1em; background-color:#f5f5f5; border:1px solid rgba(0, 0, 0, 0.15); border-radius:4px;white-space:pre;} -h1 { font-size: 1.6em; font-weight: bold; padding: 0.2em 0.2em 0.8em 0.2em; } -h2 { font-size: 1.2em; font-weight: bold; padding: 1em 0.2em 0.8em 0em; } -h3 { font-size: 1em; font-weight: bold; } -.readmore { font-weight: bold; } diff --git a/apps/tal/index.php b/apps/tal/index.php deleted file mode 100644 index d847195dc9..0000000000 --- a/apps/tal/index.php +++ /dev/null @@ -1,30 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -// Check if we are a user -OCP\User::checkLoggedIn(); -OCP\App::checkAppEnabled('tal'); - -OCP\Util::addscript('tal','tal'); -OCP\Util::addscript('tal','modernizr'); -OCP\Util::addStyle('tal','tal'); - -$sections = array( - array('id' => 'intro', 'title' => 'Introduction'), - array('id' => 'example-1', 'title' => 'A simple example'), - array('id' => 'gotchas', 'title' => 'Caveats & Gotchas'), - array('id' => 'ref', 'title' => 'References'), - ); -$page = isset($_GET['page'])?trim(strip_tags($_GET['page'])):$sections[0]['id']; - -$tmpl = new OC_TALTemplate('tal', 'manual', 'user'); -$tmpl->assign('application', 'TAL'); -$tmpl->assign('page', $page); -$tmpl->assign('sections', $sections); -$tmpl->printPage(); -?> diff --git a/apps/tal/js/modernizr.js b/apps/tal/js/modernizr.js deleted file mode 100644 index c1a6a9a51d..0000000000 --- a/apps/tal/js/modernizr.js +++ /dev/null @@ -1,1265 +0,0 @@ -/*! - * Modernizr v2.5.3 - * www.modernizr.com - * - * Copyright (c) Faruk Ates, Paul Irish, Alex Sexton - * Available under the BSD and MIT licenses: www.modernizr.com/license/ - */ - -/* - * Modernizr tests which native CSS3 and HTML5 features are available in - * the current UA and makes the results available to you in two ways: - * as properties on a global Modernizr object, and as classes on the - * <html> element. This information allows you to progressively enhance - * your pages with a granular level of control over the experience. - * - * Modernizr has an optional (not included) conditional resource loader - * called Modernizr.load(), based on Yepnope.js (yepnopejs.com). - * To get a build that includes Modernizr.load(), as well as choosing - * which tests to include, go to www.modernizr.com/download/ - * - * Authors Faruk Ates, Paul Irish, Alex Sexton - * Contributors Ryan Seddon, Ben Alman - */ - -window.Modernizr = (function( window, document, undefined ) { - - var version = '2.5.3', - - Modernizr = {}, - - // option for enabling the HTML classes to be added - enableClasses = true, - - docElement = document.documentElement, - - /** - * Create our "modernizr" element that we do most feature tests on. - */ - mod = 'modernizr', - modElem = document.createElement(mod), - mStyle = modElem.style, - - /** - * Create the input element for various Web Forms feature tests. - */ - inputElem = document.createElement('input'), - - smile = ':)', - - toString = {}.toString, - - // List of property values to set for css tests. See ticket #21 - prefixes = ' -webkit- -moz- -o- -ms- '.split(' '), - - // Following spec is to expose vendor-specific style properties as: - // elem.style.WebkitBorderRadius - // and the following would be incorrect: - // elem.style.webkitBorderRadius - - // Webkit ghosts their properties in lowercase but Opera & Moz do not. - // Microsoft uses a lowercase `ms` instead of the correct `Ms` in IE8+ - // erik.eae.net/archives/2008/03/10/21.48.10/ - - // More here: github.com/Modernizr/Modernizr/issues/issue/21 - omPrefixes = 'Webkit Moz O ms', - - cssomPrefixes = omPrefixes.split(' '), - - domPrefixes = omPrefixes.toLowerCase().split(' '), - - ns = {'svg': 'http://www.w3.org/2000/svg'}, - - tests = {}, - inputs = {}, - attrs = {}, - - classes = [], - - slice = classes.slice, - - featureName, // used in testing loop - - - // Inject element with style element and some CSS rules - injectElementWithStyles = function( rule, callback, nodes, testnames ) { - - var style, ret, node, - div = document.createElement('div'), - // After page load injecting a fake body doesn't work so check if body exists - body = document.body, - // IE6 and 7 won't return offsetWidth or offsetHeight unless it's in the body element, so we fake it. - fakeBody = body ? body : document.createElement('body'); - - if ( parseInt(nodes, 10) ) { - // In order not to give false positives we create a node for each test - // This also allows the method to scale for unspecified uses - while ( nodes-- ) { - node = document.createElement('div'); - node.id = testnames ? testnames[nodes] : mod + (nodes + 1); - div.appendChild(node); - } - } - - // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed - // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element - // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements. - // msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx - // Documents served as xml will throw if using ­ so use xml friendly encoded version. See issue #277 - style = ['­','<style>', rule, '</style>'].join(''); - div.id = mod; - // IE6 will false positive on some tests due to the style element inside the test div somehow interfering offsetHeight, so insert it into body or fakebody. - // Opera will act all quirky when injecting elements in documentElement when page is served as xml, needs fakebody too. #270 - fakeBody.innerHTML += style; - fakeBody.appendChild(div); - if(!body){ - //avoid crashing IE8, if background image is used - fakeBody.style.background = ""; - docElement.appendChild(fakeBody); - } - - ret = callback(div, rule); - // If this is done after page load we don't want to remove the body so check if body exists - !body ? fakeBody.parentNode.removeChild(fakeBody) : div.parentNode.removeChild(div); - - return !!ret; - - }, - - - // adapted from matchMedia polyfill - // by Scott Jehl and Paul Irish - // gist.github.com/786768 - testMediaQuery = function( mq ) { - - var matchMedia = window.matchMedia || window.msMatchMedia; - if ( matchMedia ) { - return matchMedia(mq).matches; - } - - var bool; - - injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) { - bool = (window.getComputedStyle ? - getComputedStyle(node, null) : - node.currentStyle)['position'] == 'absolute'; - }); - - return bool; - - }, - - - /** - * isEventSupported determines if a given element supports the given event - * function from yura.thinkweb2.com/isEventSupported/ - */ - isEventSupported = (function() { - - var TAGNAMES = { - 'select': 'input', 'change': 'input', - 'submit': 'form', 'reset': 'form', - 'error': 'img', 'load': 'img', 'abort': 'img' - }; - - function isEventSupported( eventName, element ) { - - element = element || document.createElement(TAGNAMES[eventName] || 'div'); - eventName = 'on' + eventName; - - // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those - var isSupported = eventName in element; - - if ( !isSupported ) { - // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element - if ( !element.setAttribute ) { - element = document.createElement('div'); - } - if ( element.setAttribute && element.removeAttribute ) { - element.setAttribute(eventName, ''); - isSupported = is(element[eventName], 'function'); - - // If property was created, "remove it" (by setting value to `undefined`) - if ( !is(element[eventName], 'undefined') ) { - element[eventName] = undefined; - } - element.removeAttribute(eventName); - } - } - - element = null; - return isSupported; - } - return isEventSupported; - })(); - - // hasOwnProperty shim by kangax needed for Safari 2.0 support - var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty; - if ( !is(_hasOwnProperty, 'undefined') && !is(_hasOwnProperty.call, 'undefined') ) { - hasOwnProperty = function (object, property) { - return _hasOwnProperty.call(object, property); - }; - } - else { - hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */ - return ((property in object) && is(object.constructor.prototype[property], 'undefined')); - }; - } - - // Taken from ES5-shim https://github.com/kriskowal/es5-shim/blob/master/es5-shim.js - // ES-5 15.3.4.5 - // http://es5.github.com/#x15.3.4.5 - - if (!Function.prototype.bind) { - - Function.prototype.bind = function bind(that) { - - var target = this; - - if (typeof target != "function") { - throw new TypeError(); - } - - var args = slice.call(arguments, 1), - bound = function () { - - if (this instanceof bound) { - - var F = function(){}; - F.prototype = target.prototype; - var self = new F; - - var result = target.apply( - self, - args.concat(slice.call(arguments)) - ); - if (Object(result) === result) { - return result; - } - return self; - - } else { - - return target.apply( - that, - args.concat(slice.call(arguments)) - ); - - } - - }; - - return bound; - }; - } - - /** - * setCss applies given styles to the Modernizr DOM node. - */ - function setCss( str ) { - mStyle.cssText = str; - } - - /** - * setCssAll extrapolates all vendor-specific css strings. - */ - function setCssAll( str1, str2 ) { - return setCss(prefixes.join(str1 + ';') + ( str2 || '' )); - } - - /** - * is returns a boolean for if typeof obj is exactly type. - */ - function is( obj, type ) { - return typeof obj === type; - } - - /** - * contains returns a boolean for if substr is found within str. - */ - function contains( str, substr ) { - return !!~('' + str).indexOf(substr); - } - - /** - * testProps is a generic CSS / DOM property test; if a browser supports - * a certain property, it won't return undefined for it. - * A supported CSS property returns empty string when its not yet set. - */ - function testProps( props, prefixed ) { - for ( var i in props ) { - if ( mStyle[ props[i] ] !== undefined ) { - return prefixed == 'pfx' ? props[i] : true; - } - } - return false; - } - - /** - * testDOMProps is a generic DOM property test; if a browser supports - * a certain property, it won't return undefined for it. - */ - function testDOMProps( props, obj, elem ) { - for ( var i in props ) { - var item = obj[props[i]]; - if ( item !== undefined) { - - // return the property name as a string - if (elem === false) return props[i]; - - // let's bind a function - if (is(item, 'function')){ - // default to autobind unless override - return item.bind(elem || obj); - } - - // return the unbound function or obj or value - return item; - } - } - return false; - } - - /** - * testPropsAll tests a list of DOM properties we want to check against. - * We specify literally ALL possible (known and/or likely) properties on - * the element including the non-vendor prefixed one, for forward- - * compatibility. - */ - function testPropsAll( prop, prefixed, elem ) { - - var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1), - props = (prop + ' ' + cssomPrefixes.join(ucProp + ' ') + ucProp).split(' '); - - // did they call .prefixed('boxSizing') or are we just testing a prop? - if(is(prefixed, "string") || is(prefixed, "undefined")) { - return testProps(props, prefixed); - - // otherwise, they called .prefixed('requestAnimationFrame', window[, elem]) - } else { - props = (prop + ' ' + (domPrefixes).join(ucProp + ' ') + ucProp).split(' '); - return testDOMProps(props, prefixed, elem); - } - } - - /** - * testBundle tests a list of CSS features that require element and style injection. - * By bundling them together we can reduce the need to touch the DOM multiple times. - */ - /*>>testBundle*/ - var testBundle = (function( styles, tests ) { - var style = styles.join(''), - len = tests.length; - - injectElementWithStyles(style, function( node, rule ) { - var style = document.styleSheets[document.styleSheets.length - 1], - // IE8 will bork if you create a custom build that excludes both fontface and generatedcontent tests. - // So we check for cssRules and that there is a rule available - // More here: github.com/Modernizr/Modernizr/issues/288 & github.com/Modernizr/Modernizr/issues/293 - cssText = style ? (style.cssRules && style.cssRules[0] ? style.cssRules[0].cssText : style.cssText || '') : '', - children = node.childNodes, hash = {}; - - while ( len-- ) { - hash[children[len].id] = children[len]; - } - - /*>>touch*/ Modernizr['touch'] = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch || (hash['touch'] && hash['touch'].offsetTop) === 9; /*>>touch*/ - /*>>csstransforms3d*/ Modernizr['csstransforms3d'] = (hash['csstransforms3d'] && hash['csstransforms3d'].offsetLeft) === 9 && hash['csstransforms3d'].offsetHeight === 3; /*>>csstransforms3d*/ - /*>>generatedcontent*/Modernizr['generatedcontent'] = (hash['generatedcontent'] && hash['generatedcontent'].offsetHeight) >= 1; /*>>generatedcontent*/ - /*>>fontface*/ Modernizr['fontface'] = /src/i.test(cssText) && - cssText.indexOf(rule.split(' ')[0]) === 0; /*>>fontface*/ - }, len, tests); - - })([ - // Pass in styles to be injected into document - /*>>fontface*/ '@font-face {font-family:"font";src:url("https://")}' /*>>fontface*/ - - /*>>touch*/ ,['@media (',prefixes.join('touch-enabled),('),mod,')', - '{#touch{top:9px;position:absolute}}'].join('') /*>>touch*/ - - /*>>csstransforms3d*/ ,['@media (',prefixes.join('transform-3d),('),mod,')', - '{#csstransforms3d{left:9px;position:absolute;height:3px;}}'].join('')/*>>csstransforms3d*/ - - /*>>generatedcontent*/,['#generatedcontent:after{content:"',smile,'";visibility:hidden}'].join('') /*>>generatedcontent*/ - ], - [ - /*>>fontface*/ 'fontface' /*>>fontface*/ - /*>>touch*/ ,'touch' /*>>touch*/ - /*>>csstransforms3d*/ ,'csstransforms3d' /*>>csstransforms3d*/ - /*>>generatedcontent*/,'generatedcontent' /*>>generatedcontent*/ - - ]);/*>>testBundle*/ - - - /** - * Tests - * ----- - */ - - // The *new* flexbox - // dev.w3.org/csswg/css3-flexbox - - tests['flexbox'] = function() { - return testPropsAll('flexOrder'); - }; - - // The *old* flexbox - // www.w3.org/TR/2009/WD-css3-flexbox-20090723/ - - tests['flexbox-legacy'] = function() { - return testPropsAll('boxDirection'); - }; - - // On the S60 and BB Storm, getContext exists, but always returns undefined - // so we actually have to call getContext() to verify - // github.com/Modernizr/Modernizr/issues/issue/97/ - - tests['canvas'] = function() { - var elem = document.createElement('canvas'); - return !!(elem.getContext && elem.getContext('2d')); - }; - - tests['canvastext'] = function() { - return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function')); - }; - - // this test initiates a new webgl context. - // webk.it/70117 is tracking a legit feature detect proposal - - tests['webgl'] = function() { - try { - var canvas = document.createElement('canvas'), - ret; - ret = !!(window.WebGLRenderingContext && (canvas.getContext('experimental-webgl') || canvas.getContext('webgl'))); - canvas = undefined; - } catch (e){ - ret = false; - } - return ret; - }; - - /* - * The Modernizr.touch test only indicates if the browser supports - * touch events, which does not necessarily reflect a touchscreen - * device, as evidenced by tablets running Windows 7 or, alas, - * the Palm Pre / WebOS (touch) phones. - * - * Additionally, Chrome (desktop) used to lie about its support on this, - * but that has since been rectified: crbug.com/36415 - * - * We also test for Firefox 4 Multitouch Support. - * - * For more info, see: modernizr.github.com/Modernizr/touch.html - */ - - tests['touch'] = function() { - return Modernizr['touch']; - }; - - /** - * geolocation tests for the new Geolocation API specification. - * This test is a standards compliant-only test; for more complete - * testing, including a Google Gears fallback, please see: - * code.google.com/p/geo-location-javascript/ - * or view a fallback solution using google's geo API: - * gist.github.com/366184 - */ - tests['geolocation'] = function() { - return !!navigator.geolocation; - }; - - // Per 1.6: - // This used to be Modernizr.crosswindowmessaging but the longer - // name has been deprecated in favor of a shorter and property-matching one. - // The old API is still available in 1.6, but as of 2.0 will throw a warning, - // and in the first release thereafter disappear entirely. - tests['postmessage'] = function() { - return !!window.postMessage; - }; - - - // Chrome incognito mode used to throw an exception when using openDatabase - // It doesn't anymore. - tests['websqldatabase'] = function() { - return !!window.openDatabase; - }; - - // Vendors had inconsistent prefixing with the experimental Indexed DB: - // - Webkit's implementation is accessible through webkitIndexedDB - // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB - // For speed, we don't test the legacy (and beta-only) indexedDB - tests['indexedDB'] = function() { - return !!testPropsAll("indexedDB",window); - }; - - // documentMode logic from YUI to filter out IE8 Compat Mode - // which false positives. - tests['hashchange'] = function() { - return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7); - }; - - // Per 1.6: - // This used to be Modernizr.historymanagement but the longer - // name has been deprecated in favor of a shorter and property-matching one. - // The old API is still available in 1.6, but as of 2.0 will throw a warning, - // and in the first release thereafter disappear entirely. - tests['history'] = function() { - return !!(window.history && history.pushState); - }; - - tests['draganddrop'] = function() { - var div = document.createElement('div'); - return ('draggable' in div) || ('ondragstart' in div && 'ondrop' in div); - }; - - // FIXME: Once FF10 is sunsetted, we can drop prefixed MozWebSocket - // bugzil.la/695635 - tests['websockets'] = function() { - for ( var i = -1, len = cssomPrefixes.length; ++i < len; ){ - if ( window[cssomPrefixes[i] + 'WebSocket'] ){ - return true; - } - } - return 'WebSocket' in window; - }; - - - // css-tricks.com/rgba-browser-support/ - tests['rgba'] = function() { - // Set an rgba() color and check the returned value - - setCss('background-color:rgba(150,255,150,.5)'); - - return contains(mStyle.backgroundColor, 'rgba'); - }; - - tests['hsla'] = function() { - // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally, - // except IE9 who retains it as hsla - - setCss('background-color:hsla(120,40%,100%,.5)'); - - return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla'); - }; - - tests['multiplebgs'] = function() { - // Setting multiple images AND a color on the background shorthand property - // and then querying the style.background property value for the number of - // occurrences of "url(" is a reliable method for detecting ACTUAL support for this! - - setCss('background:url(https://),url(https://),red url(https://)'); - - // If the UA supports multiple backgrounds, there should be three occurrences - // of the string "url(" in the return value for elemStyle.background - - return /(url\s*\(.*?){3}/.test(mStyle.background); - }; - - - // In testing support for a given CSS property, it's legit to test: - // `elem.style[styleName] !== undefined` - // If the property is supported it will return an empty string, - // if unsupported it will return undefined. - - // We'll take advantage of this quick test and skip setting a style - // on our modernizr element, but instead just testing undefined vs - // empty string. - - - tests['backgroundsize'] = function() { - return testPropsAll('backgroundSize'); - }; - - tests['borderimage'] = function() { - return testPropsAll('borderImage'); - }; - - - // Super comprehensive table about all the unique implementations of - // border-radius: muddledramblings.com/table-of-css3-border-radius-compliance - - tests['borderradius'] = function() { - return testPropsAll('borderRadius'); - }; - - // WebOS unfortunately false positives on this test. - tests['boxshadow'] = function() { - return testPropsAll('boxShadow'); - }; - - // FF3.0 will false positive on this test - tests['textshadow'] = function() { - return document.createElement('div').style.textShadow === ''; - }; - - - tests['opacity'] = function() { - // Browsers that actually have CSS Opacity implemented have done so - // according to spec, which means their return values are within the - // range of [0.0,1.0] - including the leading zero. - - setCssAll('opacity:.55'); - - // The non-literal . in this regex is intentional: - // German Chrome returns this value as 0,55 - // github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632 - return /^0.55$/.test(mStyle.opacity); - }; - - - // Note, Android < 4 will pass this test, but can only animate - // a single property at a time - // daneden.me/2011/12/putting-up-with-androids-bullshit/ - tests['cssanimations'] = function() { - return testPropsAll('animationName'); - }; - - - tests['csscolumns'] = function() { - return testPropsAll('columnCount'); - }; - - - tests['cssgradients'] = function() { - /** - * For CSS Gradients syntax, please see: - * webkit.org/blog/175/introducing-css-gradients/ - * developer.mozilla.org/en/CSS/-moz-linear-gradient - * developer.mozilla.org/en/CSS/-moz-radial-gradient - * dev.w3.org/csswg/css3-images/#gradients- - */ - - var str1 = 'background-image:', - str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));', - str3 = 'linear-gradient(left top,#9f9, white);'; - - setCss( - // legacy webkit syntax (FIXME: remove when syntax not in use anymore) - (str1 + '-webkit- '.split(' ').join(str2 + str1) - // standard syntax // trailing 'background-image:' - + prefixes.join(str3 + str1)).slice(0, -str1.length) - ); - - return contains(mStyle.backgroundImage, 'gradient'); - }; - - - tests['cssreflections'] = function() { - return testPropsAll('boxReflect'); - }; - - - tests['csstransforms'] = function() { - return !!testPropsAll('transform'); - }; - - - tests['csstransforms3d'] = function() { - - var ret = !!testPropsAll('perspective'); - - // Webkit's 3D transforms are passed off to the browser's own graphics renderer. - // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in - // some conditions. As a result, Webkit typically recognizes the syntax but - // will sometimes throw a false positive, thus we must do a more thorough check: - if ( ret && 'webkitPerspective' in docElement.style ) { - - // Webkit allows this media query to succeed only if the feature is enabled. - // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }` - ret = Modernizr['csstransforms3d']; - } - return ret; - }; - - - tests['csstransitions'] = function() { - return testPropsAll('transition'); - }; - - - /*>>fontface*/ - // @font-face detection routine by Diego Perini - // javascript.nwbox.com/CSSSupport/ - - // false positives in WebOS: github.com/Modernizr/Modernizr/issues/342 - tests['fontface'] = function() { - return Modernizr['fontface']; - }; - /*>>fontface*/ - - // CSS generated content detection - tests['generatedcontent'] = function() { - return Modernizr['generatedcontent']; - }; - - - - // These tests evaluate support of the video/audio elements, as well as - // testing what types of content they support. - // - // We're using the Boolean constructor here, so that we can extend the value - // e.g. Modernizr.video // true - // Modernizr.video.ogg // 'probably' - // - // Codec values from : github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845 - // thx to NielsLeenheer and zcorpan - - // Note: in some older browsers, "no" was a return value instead of empty string. - // It was live in FF3.5.0 and 3.5.1, but fixed in 3.5.2 - // It was also live in Safari 4.0.0 - 4.0.4, but fixed in 4.0.5 - - tests['video'] = function() { - var elem = document.createElement('video'), - bool = false; - - // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224 - try { - if ( bool = !!elem.canPlayType ) { - bool = new Boolean(bool); - bool.ogg = elem.canPlayType('video/ogg; codecs="theora"') .replace(/^no$/,''); - - bool.h264 = elem.canPlayType('video/mp4; codecs="avc1.42E01E"') .replace(/^no$/,''); - - bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,''); - } - - } catch(e) { } - - return bool; - }; - - tests['audio'] = function() { - var elem = document.createElement('audio'), - bool = false; - - try { - if ( bool = !!elem.canPlayType ) { - bool = new Boolean(bool); - bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,''); - bool.mp3 = elem.canPlayType('audio/mpeg;') .replace(/^no$/,''); - - // Mimetypes accepted: - // developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements - // bit.ly/iphoneoscodecs - bool.wav = elem.canPlayType('audio/wav; codecs="1"') .replace(/^no$/,''); - bool.m4a = ( elem.canPlayType('audio/x-m4a;') || - elem.canPlayType('audio/aac;')) .replace(/^no$/,''); - } - } catch(e) { } - - return bool; - }; - - - // In FF4, if disabled, window.localStorage should === null. - - // Normally, we could not test that directly and need to do a - // `('localStorage' in window) && ` test first because otherwise Firefox will - // throw bugzil.la/365772 if cookies are disabled - - // Also in iOS5 Private Browsing mode, attepting to use localStorage.setItem - // will throw the exception: - // QUOTA_EXCEEDED_ERRROR DOM Exception 22. - // Peculiarly, getItem and removeItem calls do not throw. - - // Because we are forced to try/catch this, we'll go aggressive. - - // Just FWIW: IE8 Compat mode supports these features completely: - // www.quirksmode.org/dom/html5.html - // But IE8 doesn't support either with local files - - tests['localstorage'] = function() { - try { - localStorage.setItem(mod, mod); - localStorage.removeItem(mod); - return true; - } catch(e) { - return false; - } - }; - - tests['sessionstorage'] = function() { - try { - sessionStorage.setItem(mod, mod); - sessionStorage.removeItem(mod); - return true; - } catch(e) { - return false; - } - }; - - - tests['webworkers'] = function() { - return !!window.Worker; - }; - - - tests['applicationcache'] = function() { - return !!window.applicationCache; - }; - - - // Thanks to Erik Dahlstrom - tests['svg'] = function() { - return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect; - }; - - // specifically for SVG inline in HTML, not within XHTML - // test page: paulirish.com/demo/inline-svg - tests['inlinesvg'] = function() { - var div = document.createElement('div'); - div.innerHTML = '<svg/>'; - return (div.firstChild && div.firstChild.namespaceURI) == ns.svg; - }; - - // SVG SMIL animation - tests['smil'] = function() { - return !!document.createElementNS && /SVGAnimate/.test(toString.call(document.createElementNS(ns.svg, 'animate'))); - }; - - // This test is only for clip paths in SVG proper, not clip paths on HTML content - // demo: srufaculty.sru.edu/david.dailey/svg/newstuff/clipPath4.svg - - // However read the comments to dig into applying SVG clippaths to HTML content here: - // github.com/Modernizr/Modernizr/issues/213#issuecomment-1149491 - tests['svgclippaths'] = function() { - return !!document.createElementNS && /SVGClipPath/.test(toString.call(document.createElementNS(ns.svg, 'clipPath'))); - }; - - // input features and input types go directly onto the ret object, bypassing the tests loop. - // Hold this guy to execute in a moment. - function webforms() { - // Run through HTML5's new input attributes to see if the UA understands any. - // We're using f which is the <input> element created early on - // Mike Taylr has created a comprehensive resource for testing these attributes - // when applied to all input types: - // miketaylr.com/code/input-type-attr.html - // spec: www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary - - // Only input placeholder is tested while textarea's placeholder is not. - // Currently Safari 4 and Opera 11 have support only for the input placeholder - // Both tests are available in feature-detects/forms-placeholder.js - Modernizr['input'] = (function( props ) { - for ( var i = 0, len = props.length; i < len; i++ ) { - attrs[ props[i] ] = !!(props[i] in inputElem); - } - if (attrs.list){ - // safari false positive's on datalist: webk.it/74252 - // see also github.com/Modernizr/Modernizr/issues/146 - attrs.list = !!(document.createElement('datalist') && window.HTMLDataListElement); - } - return attrs; - })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' ')); - - // Run through HTML5's new input types to see if the UA understands any. - // This is put behind the tests runloop because it doesn't return a - // true/false like all the other tests; instead, it returns an object - // containing each input type with its corresponding true/false value - - // Big thanks to @miketaylr for the html5 forms expertise. miketaylr.com/ - Modernizr['inputtypes'] = (function(props) { - - for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) { - - inputElem.setAttribute('type', inputElemType = props[i]); - bool = inputElem.type !== 'text'; - - // We first check to see if the type we give it sticks.. - // If the type does, we feed it a textual value, which shouldn't be valid. - // If the value doesn't stick, we know there's input sanitization which infers a custom UI - if ( bool ) { - - inputElem.value = smile; - inputElem.style.cssText = 'position:absolute;visibility:hidden;'; - - if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) { - - docElement.appendChild(inputElem); - defaultView = document.defaultView; - - // Safari 2-4 allows the smiley as a value, despite making a slider - bool = defaultView.getComputedStyle && - defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' && - // Mobile android web browser has false positive, so must - // check the height to see if the widget is actually there. - (inputElem.offsetHeight !== 0); - - docElement.removeChild(inputElem); - - } else if ( /^(search|tel)$/.test(inputElemType) ){ - // Spec doesnt define any special parsing or detectable UI - // behaviors so we pass these through as true - - // Interestingly, opera fails the earlier test, so it doesn't - // even make it here. - - } else if ( /^(url|email)$/.test(inputElemType) ) { - // Real url and email support comes with prebaked validation. - bool = inputElem.checkValidity && inputElem.checkValidity() === false; - - } else if ( /^color$/.test(inputElemType) ) { - // chuck into DOM and force reflow for Opera bug in 11.00 - // github.com/Modernizr/Modernizr/issues#issue/159 - docElement.appendChild(inputElem); - docElement.offsetWidth; - bool = inputElem.value != smile; - docElement.removeChild(inputElem); - - } else { - // If the upgraded input compontent rejects the :) text, we got a winner - bool = inputElem.value != smile; - } - } - - inputs[ props[i] ] = !!bool; - } - return inputs; - })('search tel url email datetime date month week time datetime-local number range color'.split(' ')); - } - - - // End of test definitions - // ----------------------- - - - - // Run through all tests and detect their support in the current UA. - // todo: hypothetically we could be doing an array of tests and use a basic loop here. - for ( var feature in tests ) { - if ( hasOwnProperty(tests, feature) ) { - // run the test, throw the return value into the Modernizr, - // then based on that boolean, define an appropriate className - // and push it into an array of classes we'll join later. - featureName = feature.toLowerCase(); - Modernizr[featureName] = tests[feature](); - - classes.push((Modernizr[featureName] ? '' : 'no-') + featureName); - } - } - - // input tests need to run. - Modernizr.input || webforms(); - - - /** - * addTest allows the user to define their own feature tests - * the result will be added onto the Modernizr object, - * as well as an appropriate className set on the html element - * - * @param feature - String naming the feature - * @param test - Function returning true if feature is supported, false if not - */ - Modernizr.addTest = function ( feature, test ) { - if ( typeof feature == 'object' ) { - for ( var key in feature ) { - if ( hasOwnProperty( feature, key ) ) { - Modernizr.addTest( key, feature[ key ] ); - } - } - } else { - - feature = feature.toLowerCase(); - - if ( Modernizr[feature] !== undefined ) { - // we're going to quit if you're trying to overwrite an existing test - // if we were to allow it, we'd do this: - // var re = new RegExp("\\b(no-)?" + feature + "\\b"); - // docElement.className = docElement.className.replace( re, '' ); - // but, no rly, stuff 'em. - return Modernizr; - } - - test = typeof test == 'function' ? test() : test; - - docElement.className += ' ' + (test ? '' : 'no-') + feature; - Modernizr[feature] = test; - - } - - return Modernizr; // allow chaining. - }; - - - // Reset modElem.cssText to nothing to reduce memory footprint. - setCss(''); - modElem = inputElem = null; - - //>>BEGIN IEPP - // Enable HTML 5 elements for styling in IE & add HTML5 css - /*! HTML5 Shiv v3.4 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */ - ;(function(window, document) { - - /** Preset options */ - var options = window.html5 || {}; - - /** Used to skip problem elements */ - var reSkip = /^<|^(?:button|form|map|select|textarea)$/i; - - /** Detect whether the browser supports default html5 styles */ - var supportsHtml5Styles; - - /** Detect whether the browser supports unknown elements */ - var supportsUnknownElements; - - (function() { - var a = document.createElement('a'); - - a.innerHTML = '<xyz></xyz>'; - - //if the hidden property is implemented we can assume, that the browser supports HTML5 Styles - supportsHtml5Styles = ('hidden' in a); - supportsUnknownElements = a.childNodes.length == 1 || (function() { - // assign a false positive if unable to shiv - try { - (document.createElement)('a'); - } catch(e) { - return true; - } - var frag = document.createDocumentFragment(); - return ( - typeof frag.cloneNode == 'undefined' || - typeof frag.createDocumentFragment == 'undefined' || - typeof frag.createElement == 'undefined' - ); - }()); - - }()); - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a style sheet with the given CSS text and adds it to the document. - * @private - * @param {Document} ownerDocument The document. - * @param {String} cssText The CSS text. - * @returns {StyleSheet} The style element. - */ - function addStyleSheet(ownerDocument, cssText) { - var p = ownerDocument.createElement('p'), - parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; - - p.innerHTML = 'x<style>' + cssText + '</style>'; - return parent.insertBefore(p.lastChild, parent.firstChild); - } - - /** - * Returns the value of `html5.elements` as an array. - * @private - * @returns {Array} An array of shived element node names. - */ - function getElements() { - var elements = html5.elements; - return typeof elements == 'string' ? elements.split(' ') : elements; - } - - /** - * Shivs the `createElement` and `createDocumentFragment` methods of the document. - * @private - * @param {Document|DocumentFragment} ownerDocument The document. - */ - function shivMethods(ownerDocument) { - var cache = {}, - docCreateElement = ownerDocument.createElement, - docCreateFragment = ownerDocument.createDocumentFragment, - frag = docCreateFragment(); - - ownerDocument.createElement = function(nodeName) { - // Avoid adding some elements to fragments in IE < 9 because - // * Attributes like `name` or `type` cannot be set/changed once an element - // is inserted into a document/fragment - // * Link elements with `src` attributes that are inaccessible, as with - // a 403 response, will cause the tab/window to crash - // * Script elements appended to fragments will execute when their `src` - // or `text` property is set - var node = (cache[nodeName] || (cache[nodeName] = docCreateElement(nodeName))).cloneNode(); - return html5.shivMethods && node.canHaveChildren && !reSkip.test(nodeName) ? frag.appendChild(node) : node; - }; - - ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + - 'var n=f.cloneNode(),c=n.createElement;' + - 'h.shivMethods&&(' + - // unroll the `createElement` calls - getElements().join().replace(/\w+/g, function(nodeName) { - cache[nodeName] = docCreateElement(nodeName); - frag.createElement(nodeName); - return 'c("' + nodeName + '")'; - }) + - ');return n}' - )(html5, frag); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Shivs the given document. - * @memberOf html5 - * @param {Document} ownerDocument The document to shiv. - * @returns {Document} The shived document. - */ - function shivDocument(ownerDocument) { - var shived; - if (ownerDocument.documentShived) { - return ownerDocument; - } - if (html5.shivCSS && !supportsHtml5Styles) { - shived = !!addStyleSheet(ownerDocument, - // corrects block display not defined in IE6/7/8/9 - 'article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}' + - // corrects audio display not defined in IE6/7/8/9 - 'audio{display:none}' + - // corrects canvas and video display not defined in IE6/7/8/9 - 'canvas,video{display:inline-block;*display:inline;*zoom:1}' + - // corrects 'hidden' attribute and audio[controls] display not present in IE7/8/9 - '[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}' + - // adds styling not present in IE6/7/8/9 - 'mark{background:#FF0;color:#000}' - ); - } - if (!supportsUnknownElements) { - shived = !shivMethods(ownerDocument); - } - if (shived) { - ownerDocument.documentShived = shived; - } - return ownerDocument; - } - - /*--------------------------------------------------------------------------*/ - - /** - * The `html5` object is exposed so that more elements can be shived and - * existing shiving can be detected on iframes. - * @type Object - * @example - * - * // options can be changed before the script is included - * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; - */ - var html5 = { - - /** - * An array or space separated string of node names of the elements to shiv. - * @memberOf html5 - * @type Array|String - */ - 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video', - - /** - * A flag to indicate that the HTML5 style sheet should be inserted. - * @memberOf html5 - * @type Boolean - */ - 'shivCSS': !(options.shivCSS === false), - - /** - * A flag to indicate that the document's `createElement` and `createDocumentFragment` - * methods should be overwritten. - * @memberOf html5 - * @type Boolean - */ - 'shivMethods': !(options.shivMethods === false), - - /** - * A string to describe the type of `html5` object ("default" or "default print"). - * @memberOf html5 - * @type String - */ - 'type': 'default', - - // shivs the document according to the specified `html5` object options - 'shivDocument': shivDocument - }; - - /*--------------------------------------------------------------------------*/ - - // expose html5 - window.html5 = html5; - - // shiv the document - shivDocument(document); - - }(this, document)); - - //>>END IEPP - - // Assign private properties to the return object with prefix - Modernizr._version = version; - - // expose these for the plugin API. Look in the source for how to join() them against your input - Modernizr._prefixes = prefixes; - Modernizr._domPrefixes = domPrefixes; - Modernizr._cssomPrefixes = cssomPrefixes; - - // Modernizr.mq tests a given media query, live against the current state of the window - // A few important notes: - // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false - // * A max-width or orientation query will be evaluated against the current state, which may change later. - // * You must specify values. Eg. If you are testing support for the min-width media query use: - // Modernizr.mq('(min-width:0)') - // usage: - // Modernizr.mq('only screen and (max-width:768)') - Modernizr.mq = testMediaQuery; - - // Modernizr.hasEvent() detects support for a given event, with an optional element to test on - // Modernizr.hasEvent('gesturestart', elem) - Modernizr.hasEvent = isEventSupported; - - // Modernizr.testProp() investigates whether a given style property is recognized - // Note that the property names must be provided in the camelCase variant. - // Modernizr.testProp('pointerEvents') - Modernizr.testProp = function(prop){ - return testProps([prop]); - }; - - // Modernizr.testAllProps() investigates whether a given style property, - // or any of its vendor-prefixed variants, is recognized - // Note that the property names must be provided in the camelCase variant. - // Modernizr.testAllProps('boxSizing') - Modernizr.testAllProps = testPropsAll; - - - - // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards - // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... }) - Modernizr.testStyles = injectElementWithStyles; - - - // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input - // Modernizr.prefixed('boxSizing') // 'MozBoxSizing' - - // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style. - // Return values will also be the camelCase variant, if you need to translate that to hypenated style use: - // - // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-'); - - // If you're trying to ascertain which transition end event to bind to, you might do something like... - // - // var transEndEventNames = { - // 'WebkitTransition' : 'webkitTransitionEnd', - // 'MozTransition' : 'transitionend', - // 'OTransition' : 'oTransitionEnd', - // 'msTransition' : 'MsTransitionEnd', - // 'transition' : 'transitionend' - // }, - // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; - - Modernizr.prefixed = function(prop, obj, elem){ - if(!obj) { - return testPropsAll(prop, 'pfx'); - } else { - // Testing DOM property e.g. Modernizr.prefixed('requestAnimationFrame', window) // 'mozRequestAnimationFrame' - return testPropsAll(prop, obj, elem); - } - }; - - - - // Remove "no-js" class from <html> element, if it exists: - docElement.className = docElement.className.replace(/(^|\s)no-js(\s|$)/, '$1$2') + - - // Add the new classes to the <html> element. - (enableClasses ? ' js ' + classes.join(' ') : ''); - - return Modernizr; - -})(this, this.document); diff --git a/apps/tal/js/tal.js b/apps/tal/js/tal.js deleted file mode 100644 index c4c6469440..0000000000 --- a/apps/tal/js/tal.js +++ /dev/null @@ -1,32 +0,0 @@ - -$(document).ready(function(){ - $('#manual nav').keydown(function(event) { - if(event.which == 13) { - $('#manual ol').click(); - } - }); - $('#manual nav').click(function(event){ - var $tgt = $(event.target); - if ($tgt.is('li') || $tgt.is('a')) { - var item = $tgt.is('li')?$($tgt):($tgt).parent(); - var section = $('#manual section'); - var id = item.data('id'); - item.addClass('active'); - var oldpage = section.data('id'); - if(oldpage){ - $('#manual li[data-id="'+oldpage+'"]').removeClass('active'); - } - $.getJSON(OC.filePath('tal', 'ajax', 'loadpage.php'),{'id':id},function(jsondata){ - if(jsondata.status == 'success'){ - $('#manual li[data-id="'+id+'"]').addClass('active'); - section.replaceWith(jsondata.data.page); - section.data('id', id); - } - else{ - OC.dialogs.alert(jsondata.data.message, t('core', 'Error')); - } - }); - } - return false; - }); -}); \ No newline at end of file diff --git a/apps/tal/lib/paths.php b/apps/tal/lib/paths.php deleted file mode 100644 index b61d52c0f4..0000000000 --- a/apps/tal/lib/paths.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -/** - * This class provides TAL templates for owncloud. - */ -class OC_TALTemplate extends OC_Template { -} \ No newline at end of file diff --git a/apps/tal/lib/tall10n.php b/apps/tal/lib/tall10n.php deleted file mode 100644 index 81ebfe4904..0000000000 --- a/apps/tal/lib/tall10n.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -//require_once 'PHPTAL/TranslationService.php'; - - -class OC_TALL10N extends OC_L10N implements PHPTAL_TranslationService { - private $encoding = 'UTF-8'; - private $vars = array(); - //private $lang = ''; - //private $app = ''; - - /** - * @brief The constructor - * @param $app the app requesting l10n - * @param $lang default: null Language - * @returns OC_L10N-Object - * - * If language is not set, the constructor tries to find the right - * language. - */ - public function __construct($app, $lang = null){ - //$this->app = $app; - //$this->lang = $lang; - parent::__construct($app, $lang); - } - - /** - * Set the target language for translations. - * @return string - chosen language - */ - function setLanguage(/*...*/) { - $langs = func_get_args(); - $this->language = $langs[0]; - } - - /** - * PHPTAL will inform translation service what encoding page uses. - * Output of translate() must be in this encoding. - * NOTE: Currently not used (and probably won't be as we use utf-8 all over?). - */ - function setEncoding($encoding) { - $this->encoding = $encoding; - } - - /** - * Set the domain to use for translations (if different parts of application are translated in different files. This is not for language selection). - */ - function useDomain($domain) { - if(!$domain) { - return; - } - error_log('useDomain: '.$domain); - $this->app = $domain; - $this->init(); - } - - /** - * Set value of a variable used in translation key. - * - * You should use it to replace all {key}s with values in translated strings. - * - * @param string $key - name of the variable - * @param string $value - */ - public function setVar($key, $value) { - error_log('setVar: '.$key.'=>'.$value); - $this->vars[$key] = $value; - } - - /** - * Translate a gettext key and interpolate variables. - * - * @param string $key - translation key, e.g. "hello {username}!" - * @param string $htmlescape - if true, you should HTML-escape translated string. You should never HTML-escape interpolated variables. - */ - function translate($key, $escape=true) { - $translations = $this->getTranslations(); - if (array_key_exists($key, $translations)) { - $v = $translations[$key]; - } else { - $v = $key; - } - - if ($escape) { - $v = htmlspecialchars($v); - } - - //while (preg_match('/\{(.*?)\}/sm', $v, $m)) { - while (preg_match('/\$\{(.*?)\}/sm', $v, $m)) { - list($src, $var) = $m; - if (!isset($this->vars[$var])) { - $v = str_replace($src, 'undefined', $v); - } else { - $v = str_replace($src, $this->vars[$var], $v); - } - } - return $v; - } -} \ No newline at end of file diff --git a/apps/tal/lib/taltemplate.php b/apps/tal/lib/taltemplate.php deleted file mode 100644 index 523e857e6f..0000000000 --- a/apps/tal/lib/taltemplate.php +++ /dev/null @@ -1,372 +0,0 @@ -<?php -/** - * kate: replace-tabs off; indent-mode Normal; keep-extra-spaces: off; tab-indents: on; - * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -function phptal_tales_remote($exp, $nothrow) { - //$exp = trim($exp, ' \t\r\n/'); - error_log(phptal_tales($exp, $nothrow)); - return "OCP\Util::linkToRemote(".phptal_tales($exp, $nothrow).")"; -} - -function phptal_tales_url($src, $nothrow) { - //$exp = trim($exp, ' \t\r\n/'); - error_log(phptal_tales($src, $nothrow)); - return "OC_TALTemplate::linkToAbsolute(".phptal_tales($src, $nothrow).")"; -} - -function phptal_tales_linkto($src, $nothrow) { - return "OC_TALTemplate::linkTo(".phptal_tales($src, $nothrow).")"; -} - -function phptal_tales_image($src, $nothrow) { - return "OC_TALTemplate::imagePath(".phptal_tales($src, $nothrow).")"; -} - -function phptal_tales_config($src, $nothrow) { - return "OC_TALTemplate::config(".phptal_tales($src, $nothrow).")"; -} - -/** - * This class provides TAL templates for owncloud. - */ -class OC_TALTemplate extends OC_Template { - /** - */ - protected $_engine = null; - protected $scripts = Array(); - protected $styles = Array(); - protected $_headers = Array(); - protected $renderas; - protected static $app = ''; - - public function __construct($app, $name, $renderas = "") { - //if(defined('DEBUG') && DEBUG) { - ini_set('display_errors', true); - //} - $this->renderas = $renderas; - $this->i18n = new OC_TALL10N($app); - $this->setEngine(new PHPTAL()); - parent::__construct($app, $name, $renderas); - //$this->fetchHeadVars(); - self::$app = $app; - //$this->assign('application', $this->app); - $this->assign('i18n', $this->i18n); - $this->assign('user', OCP\User::getUser()); - $this->assign('appinfo', OCP\App::getAppInfo($app)); - $this->assign('appajaxpath', OC::$SERVERROOT.OC_App::getAppPath($app).'/ajax'); - $this->assign('appjspath', OC::$SERVERROOT.OC_App::getAppPath($app).'/js'); - $this->assign('apptemplatepath', OC::$SERVERROOT.OC_App::getAppPath($app).'/templates'); - if($renderas) { - $this->assign('maintemplate', OC_App::getAppPath('tal').'/templates/layout.'.$renderas.'.pt'); - if($renderas == 'user') { - $this->assign('requesttoken', OC_Util::callRegister()); - } - } - //$this->assign('styles', $this->styles); - $this->assign('core_styles', !empty(OC_Util::$core_styles)?'core.css':null); - $this->assign('core_scripts', !empty(OC_Util::$core_scripts)?'core.js':null); - $request = isset($_REQUEST)?$_REQUEST:array(); - $request['post'] = isset($_POST)?$_POST:array(); - $request['get'] = isset($_GET)?$_GET:array(); - $this->assign('request', $request); - $this->assign('server', $_SERVER); - $this->assign('webroot', OC::$WEBROOT); - $this->assign('theme', OC_Config::getValue('theme')); - - $apps_paths = array(); - foreach(OC_App::getEnabledApps() as $app){ - $apps_paths[$app] = OC_App::getAppWebPath($app); - } - $this->assign( 'apps_paths', str_replace('\\/', '/',json_encode($apps_paths)),false ); // Ugly unescape slashes waiting for better solution - - // Add the js files - $jsfiles = OC_TemplateLayout::findJavascriptFiles(OC_Util::$scripts); - - foreach($jsfiles as $info) { - $root = $info[0]; - $web = $info[1]; - $file = $info[2]; - $this->scripts[] = $web.'/'.$file; - } - $this->assign('scripts',$this->scripts); - - // Add the css files - $cssfiles = OC_TemplateLayout::findStylesheetFiles(OC_Util::$styles); - - foreach($cssfiles as $info) { - $root = $info[0]; - $web = $info[1]; - $file = $info[2]; - $paths = explode('/', $file); - - $in_root = false; - foreach(OC::$APPSROOTS as $app_root) { - if($root == $app_root['path']) { - $in_root = true; - break; - } - } - - if($in_root ) { - $app = $paths[0]; - unset($paths[0]); - $path = implode('/', $paths); - $this->styles[] = OC_Helper::linkTo($app, $path); - } - else { - $this->styles[] = $web.'/'.$file; - } - } - $this->assign('styles', $this->styles); - - } - - /** - * Plug in PHPTAL object into View - * - * @name setEngine - * @access public - * @param object PHPTAL $engine - */ - public function setEngine(PHPTAL $engine) { - $view = new OC_FilesystemView('/'.OC_User::getUser()); - if(!$view->file_exists('phptal')) { - $view->mkdir('phptal'); - } - $this->_engine = $engine; - $this->_engine->setPhpCodeDestination($view->getLocalFile('/phptal/')); - $this->_engine->setTemplateRepository($_SERVER['DOCUMENT_ROOT'].OCP\Util::linkTo(self::$app, 'templates')); - $this->_engine->set('this', $this); - $this->_engine->setOutputMode(PHPTAL::HTML5); - $this->_engine->setTranslator($this->i18n); - return $this; - } - - /** - * Forces reparsing of all templates all the time. It should be used only for testing and debugging. - * It's useful if you're testing pre filters or changing code of PHPTAL itself. - * WARNING: This slows down PHPTAL very much. Never enable this on production servers! - */ - public function setForceReparse() { - OCP\Util::writeLog('tal','ForceReparse is enabled!', OCP\Util::WARN); - $this->_engine->setForceReparse(); - } - - /** - * Get PHPTAL object from View - * - * @name getEngine - * @access public - */ - public function getEngine() { - return $this->_engine; - } - - /** - * Clone PHPTAL object - * - * @access public - */ - public function __clone() { - $this->_engine = clone $this->_engine; - } - - /** - * Display template - * - * @access protected - */ - protected function _run() { - $this->_engine->setTemplate(func_get_arg(0)); - try { - echo $this->_engine->execute(); - } catch (Exception $e) { - throw new Exception($e); - } - } - - /** - * @brief check Path For Template with and without $fext - * @param $path to check - * @param $name of the template file (without suffix) - * @param $fext formfactor extension - * @return bool true when found - * - * Will set $this->template and $this->path if there is a template at - * the specified $path - */ - protected function checkPathForTemplate($path, $name, $fext) { - if ($name =='') return false; - $template = null; - if( is_file( $path.$name.$fext.'.pt' )){ - $template = $path.$name.$fext.'.pt'; - }elseif( is_file( $path.$name.'.pt' )){ - $template = $path.$name.'.pt'; - } - //error_log('Template: '.$template); - if ($template) { - $this->template = $template; - $this->path = $path; - $this->_engine->template = $this->template; - $this->_engine->setTemplate($this->template); - return true; - } - return false; - } - - /** - * @brief Assign variables - * @param $key key - * @param $value value - * @param $sanitizeHTML Ignored, as values are always sanitized unless explicitly specified not to. - * @returns true - * - * This function assigns a variable. It can be accessed via TALES expressions or ${$key} in - * the template. - * - * If the key existed before, it will be overwritten - */ - public function assign( $key, $value, $sanitizeHTML=false ){ - $this->_engine->set($key, $value); - return true; - } - - /** - * @brief Add a custom element to the header - * @param string tag tag name of the element - * @param array $attributes array of attributes for the element - * @param string $text the text content for the element - */ - public function addHeader( $tag, $attributes, $text=''){ - $this->_headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text); - } - - /** - * @brief Prints the proceeded template - * @returns true/false - * - * This function proceeds the template and prints its output. - */ - public function printPage(){ - echo $this->fetchPage(); - } - - /** - * @brief Proceeds the template - * @returns content - * - * This function proceeds the template. If $this->renderas is set, it - * will produce a full page. - */ - public function fetchPage(){ - error_log('renderas: '.$this->renderas); - if($this->renderas) { - // Add custom headers - $this->assign('headers',array_merge($this->_headers, OC_Util::$headers)); - // Add navigation entry - $navigation = OC_App::getNavigation(); - $this->assign( "navigation", $navigation); - $this->assign( "settingsnavigation", OC_App::getSettingsNavigation()); - if(array_search(OC_APP::getCurrentApp(),array('settings','admin','help'))!==false){ - $this->assign('bodyid','body-settings'); - }else{ - $this->assign('bodyid','body-user'); - } - foreach($navigation as $entry) { - if ($entry['active']) { - $this->assign( 'application', $entry['name'] ); - break; - } - } - } - //error_log('utilheaders'.print_r(array_merge($this->_headers, OC_Util::$headers), true)); - return $this->_engine->execute(); - } - - static function linkTo($src) { - //error_log('linkTo '.$src); - $parts = is_array($src)?$src:explode('/', rtrim($src, ' \t\r\n/')); - if($parts[0] == '') { - array_shift($parts); - return OCP\Util::linkTo('', implode('/', $parts)); - } elseif(count($parts) == 1) { - return OCP\Util::linkTo('', implode('/', $parts)); - } elseif(trim($parts[0] == 'core')) { - array_shift($parts); - return OCP\Util::linkTo('', implode('/', $parts)); - } else { // This should be an app. - return OCP\Util::linkTo(array_shift($parts), implode('/', $parts)); - } - } - - static function linkToAbsolute($src) { - //error_log('linkTo '.$src); - $parts = is_array($src)?$src:explode('/', rtrim($src, ' \t\r\n/')); - if($parts[0] == '') { - array_shift($parts); - return OCP\Util::linkToAbsolute('', implode('/', $parts)); - } elseif(count($parts) == 1) { - return OCP\Util::linkToAbsolute('', implode('/', $parts)); - } elseif(trim($parts[0] == 'core')) { - array_shift($parts); - return OCP\Util::linkToAbsolute('', implode('/', $parts)); - } else { // This should be an app. - return OCP\Util::linkToAbsolute(array_shift($parts), implode('/', $parts)); - } - } - - static function imagePath($src) { - //error_log('imagePath '.$src); - $parts = is_array($src)?$src:explode('/', rtrim($src, ' \t\r\n/')); - if($parts[0] == '') { - array_shift($parts); - return OCP\Util::imagePath('', implode('/', $parts)); - } elseif(count($parts) == 1) { - return OCP\Util::imagePath('', implode('/', $parts)); - } elseif(trim($parts[0] == 'core')) { - array_shift($parts); - return OCP\Util::imagePath('', implode('/', $parts)); - } else { // This should be an app. - return OCP\Util::imagePath(array_shift($parts), implode('/', $parts)); - } - } - - static function config($src) { - error_log('pref '.$src); - $parts = is_array($src)?$src:explode('/', rtrim($src, ' \t\r\n/')); - if(count($parts) < 2) { - throw new PHPTAL_Exception('Wrong argument count: config: takes no less than 2 arguments.'); - } else { - switch ($parts[0]) { - case 'sys': - return OCP\Config::getSystemValue($parts[1]); - break; - case 'app': - if(count($parts) == 2) { - return OCP\Config::getAppValue(self::app, $parts[1]); - } elseif(count($parts) == 3) { - return OCP\Config::getAppValue($parts[1], $parts[2]); - } else { - throw new PHPTAL_Exception('Wrong argument count: config:$app takes no more than 3 arguments.'); - } - break; - case 'user': - if(count($parts) == 2) { - return OCP\Config::getUserValue(OCP\User::getUser(), self::app, $parts[1]); - } elseif(count($parts) == 3) { - return OCP\Config::getUserValue(OCP\User::getUser(), $parts[1], $parts[2]); - } elseif(count($parts) == 4) { - return OCP\Config::getUserValue($parts[1], $parts[2], $parts[3]); - } else { - throw new PHPTAL_Exception('Wrong argument count: config: takes no more than 4 arguments.'); - } - break; - } - } - } -} \ No newline at end of file diff --git a/apps/tal/settings.php b/apps/tal/settings.php deleted file mode 100644 index a4eeb33344..0000000000 --- a/apps/tal/settings.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php -/** - * Copyright (c) 2012 Thomas Tanghus <thomas@tanghus.net> - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - - -OCP\JSON::checkLoggedIn(); -OCP\JSON::checkAppEnabled('tal'); - -$tmpl = new OC_TALTemplate('tal', 'settings'); -return $tmpl->fetchPage(); - -?> diff --git a/apps/tal/templates/layout.guest.pt b/apps/tal/templates/layout.guest.pt deleted file mode 100644 index 884b44a582..0000000000 --- a/apps/tal/templates/layout.guest.pt +++ /dev/null @@ -1,43 +0,0 @@ -<!DOCTYPE html> -<html metal:define-macro="page"> -<head> - <title>ownCloud - - - - - - - - - - - - - - - - - - - /> - - - - -

      -
      - -
      -
      - This is the content. -
      -
      -

      ownCloud – web services under your control

      - - diff --git a/apps/tal/templates/layout.user.pt b/apps/tal/templates/layout.user.pt deleted file mode 100644 index a945e1af7a..0000000000 --- a/apps/tal/templates/layout.user.pt +++ /dev/null @@ -1,78 +0,0 @@ - - - - - Scripts and Styles - - - - - - - - - - - - - - - - - - - - - /> - - - -
      - -
      - - - -
      - This is the content. -
      - - \ No newline at end of file diff --git a/apps/tal/templates/macros.util.pt b/apps/tal/templates/macros.util.pt deleted file mode 100644 index 0e8c590e0e..0000000000 --- a/apps/tal/templates/macros.util.pt +++ /dev/null @@ -1,56 +0,0 @@ - - - - - Utility macros - - - - -
      - -
      - - - - - - - - -function html_select_options($options, $selected, $params=array()) { - if (!is_array($selected)){ - $selected=array($selected); - } - if (isset($params['combine']) && $params['combine']){ - $options = array_combine($options, $options); - } - $value_name = $label_name = false; - if (isset($params['value'])){ - $value_name = $params['value']; - } - if (isset($params['label'])){ - $label_name = $params['label']; - } - $html = ''; - foreach($options as $value => $label){ - if ($value_name && is_array($label)){ - $value = $label[$value_name]; - } - if ($label_name && is_array($label)){ - $label = $label[$label_name]; - } - $select = in_array($value, $selected) ? ' selected="selected"' : ''; - $html .= ''."\n"; - } - return $html; -} - - - \ No newline at end of file diff --git a/apps/tal/templates/manual.pt b/apps/tal/templates/manual.pt deleted file mode 100644 index 9ad03db30b..0000000000 --- a/apps/tal/templates/manual.pt +++ /dev/null @@ -1,23 +0,0 @@ - - - - TAL Page Templates - - -
      -
      - -
      -

      Manual

      - rest of the content -
      -
      -
      - - \ No newline at end of file diff --git a/apps/tal/templates/sections.pt b/apps/tal/templates/sections.pt deleted file mode 100644 index 9dcda6ebf4..0000000000 --- a/apps/tal/templates/sections.pt +++ /dev/null @@ -1,142 +0,0 @@ - -TRUT - -
      -

      Introduction

      -

      Initializing a template

      - Before: -
      $output = new OCP\Template('app', 'template', 'user');
      - After: -
      $tmpl = new OC_TALTemplate('app', 'template', 'user');
      -

      Assigning a variable

      - Before: -
      $tmpl->assign('myvar', $myvar);
      - After: -
      $tmpl->assign('myvar', $myvar);
      - The sharp minds may have noticed that there is no difference ;-) -

      Linking to an image

      - Before: -
      -<img class="svg" src="<?php echo image_path('', 'logo-wide.svg'); ?>" alt="ownCloud" />
      -<img class="svg" src="<?php echo image_path('app', 'someimage.png'); ?>" alt="ownCloud" />
      - After: -
      -<img class="svg" tal:attributes="src image:string:logo-wide.svg" alt="ownCloud" />
      -<img class="svg" tal:attributes="src image:string:app/someimage.png" alt="ownCloud" />
      -

      Constructing a link

      - Before: -
      -<a href="<?php echo link_to('', 'index.php'); ?>">Home</a>
      -<a href="<?php echo link_to('app', 'index.php'); ?>">Some app</a>
      - After: -
      -<a tal:attributes="href linkto:string:index.php">Home</a>
      -<a tal:attributes="href linkto:string:app/index.php">Some app</a>
      -

      Link to remote service

      - Before: -
      -<link rel="stylesheet" href="<?php echo OC_Helper::linkToRemote('core.css') ?>" type="text/css" media="screen" />
      -<a href="<?php echo OC_Helper::linkToRemote('webdav') ?>">WebDAV</a>
      - After: -
      -<link rel="stylesheet" type="text/css" media="screen" tal:attributes="href remote:string:core.css" />
      -<a tal:attributes="href remote:string:webdav">WebDAV</a>
      -

      The latter produces a link to the WebDAV service on the current instance: - WebDAV

      -

      Accessing configuration

      - Before: -
      -ownCloud version: <?php echo OCP\Config::getSystemValue('version'); ?>
      -Default quota: <?php echo OCP\Config::getAppValue('files', 'default_quota'); ?>
      -Calendar time zone: <?php echo OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone'); ?>
      - After: -
      -ownCloud version: $${config:string:sys/version}
      -Default quota: $${config:string:app/files/default_quota}
      -Calendar time zone: $${config:string:user/calendar/timezone}
      - ownCloud version: ${config:string:sys/version}
      - Default quota: ${config:string:app/files/default_quota}
      - Calendar time zone: ${config:string:user/calendar/timezone}
      -

      Translating content

      - Before: -
      <p><?php echo $l->t('This will be translated.'); ?><p>
      - After: -
      <p i18n:translate="">This will be translated.<p>
      - Read more... -

      Translating content with variables

      - Before: -

      There is no standardized way to do this currently. I have seen both translation keys using printf formatting - and custom interpolation using e.g. curly brackets.

      - After: -
      -<tal:block i18n:name="username" tal:content="user" />
      -<p i18n:translate="">Your user name is ${username}.</p>
      - -

      Your user name is ${username}.

      -

      Or you can wrap it in some markup:

      -
      -<p i18n:translate="">
      -Welcome back <span i18n:name="username" tal:replace="user"/>.
      -</p>
      -

      - Welcome back . -

      - Read more... -

      Translating attributes.

      - Before: -
      <img alt="<?php echo $l->t('Log out');?>" title="<?php echo $l->t('Log out');?>" src="<?php echo image_path('', 'actions/logout.svg'); ?>" />
      - After: -
      <img tal:attributes="src image:string:/actions/logout.svg" i18n:attributes="alt;title" alt="Log out" title="Log out" />
      - See more... -

      Iterating

      -
      -$$arr = array('color' => 'red',
      -            'taste' => 'sweet',
      -            'shape' => 'round',
      -            'name'  => 'apple');
      -	
      - Before: -
      -<select size="4">
      -<?php foreach($$arr as $key=>$value) { ?>
      -<option value="<php echo $key; >" ><php echo $value; ></option>
      -</select>
      -<?php } ?>
      - After: -
      -<select size="4">
      -<option tal:repeat="item arr" tal:attributes="value repeat/item/key" tal:content="item"></option>
      -</select>
      -
      - -
      - Read more... -

      Initializing a template

      - Before: -
      
      -	After:
      -	
      
      -
      -
      -

      A simple example

      - This is actually the main template for this manual. -
      -	
      -
      -
      -

      Caveats & Gotchas

      - I know -
      -
      -

      References

      -
      -
      PHPTAL
      The PHP TAL implementation
      -
      TAL
      Template Attribute Language
      -
      TALES
      TAL Expression Syntax
      -
      METAL
      Macro Expansion Template Attribute Language
      -
      i18n namespace
      Internationalization in TAL
      -
      Zope Page Templates
      Links and specifications from the original TAL implementation
      -
      -
      diff --git a/apps/tal/templates/settings.pt b/apps/tal/templates/settings.pt deleted file mode 100644 index 1ae6eea9e7..0000000000 --- a/apps/tal/templates/settings.pt +++ /dev/null @@ -1,10 +0,0 @@ -
      -
      - TAL Page Templates for ownCloud -

      You can now create templates using TAL. As a matter of fact this section is using the internationalization namespace defined in TAL.
      - Read more about it from the links below

      - -
      -
      diff --git a/apps/tanghus-journal-2c506aa.tar.gz b/apps/tanghus-journal-2c506aa.tar.gz deleted file mode 100644 index faa1ccfe477ed1467151c94011c7c83c49f23470..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41637 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

      u&f_Ya^_ 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 C@R!#B